3rd party libraries conflicting definitions/ redefinitons - c++

I am working on Qt Platform with two separate libraries. The Problem that I am facing is that he two libraries have different declaration for int32_t.
The first library has :
#ifdef _WIN32
#if ULONG_MAX == 0xffffffff
typedef long int32_t;
#else
typedef int int32_t;
#endif
#endif
The second Library :
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
The error that I get is :
C:\Program Files (x86)\SiliconSoftware\Runtime5.1\include\msinttypes\stdint.h:91: error: C2371: 'int32_t' : redefinition; different basic types
c:\program files (x86)\matlab\r2008a\extern\include\mclmcr.h:216: see declaration of 'int32_t'
I tried following this post on stackoverflow :
Typedef redefinition (C2371) for uint32 in two 3rd-party libraries
And i tried to implement it in my code :
#define int32_t VicTorv3_int32_t
#include"mclmcr.h"
#undef int32_t
#define int32_t Silicon_int32_t
#include "stdint.h"
#undef int32_t
I still get the same error. Please help.

stdint.h is also a system include file. Chances are good that it gets included before the define/undef workaround. And when you workaround tries to include the file again, the inclusion guards do their work. You might check the situation using this:
Displaying the #include hierarchy for a C++ file in Visual Studio
I suggest moving the part where you include stdint.h to the very top of the file, before ALL other includes.
Be watchful, shadowing the system include file stdint.h with another version asks for problems.

Related

the property of the my project is configured right , but visual studio still can not open include header file

everyone , Sorry if this is such a naive question,but it really disrupts me .
I am using boost library in my project.
I think my project is configured right , in the properties of the project , in the additional include directories part :
I have provided :D:\work material\LIBRARY\BOOST2\x64\include\boost-1_71
I also provided the lib path in the linker part ..
my corresponding source code is :
#ifdef HAVE_STDINT_H
# include <stdint.h>
#else
# include <boost/cstdint.hpp>
typedef boost::int64_t int64_t;
typedef boost::uint64_t uint64_t;
typedef boost::int32_t int32_t;
typedef boost::uint32_t uint32_t;
typedef boost::int16_t int16_t;
typedef boost::uint16_t uint16_t;
typedef boost::int8_t int8_t;
typedef boost::uint8_t uint8_t;
#endif
the macro HAVE_STDINT_H is not defined .
and when compiled ,I get the error:
Error C1083 Cannot open include file: 'boost/cstdint.hpp': No such file or directory
I have compiled successfully before ,but this time it seems never will work .
sorry ,guys and gals. it is a naive question,indeed . It turns out that another project on which this project depend doesn't have the right configuration.
As I mentioned ,it successes before ,so follow pure logic ,I should try to pin down the problem in other directions .But it is a time constrained work ,I want to finish it as soon as possible ,So post it on stack overflow.

ptrdiff_t typedef collision - google-test and intel anaconda

Context
I am developing a project that requires intel's anaconda distribution, and we use googletest to test our natives. I am using clang for my compiler. When I build googletest via cmake, I get this:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-all.cc:39:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/gtest.h:58:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/internal/gtest-internal.h:39:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/internal/gtest-port.h:452:
In file included from /foo/anaconda3/envs/idp3/include/regex.h:4:
/foo/anaconda3/envs/idp3/include/tclInt.h:60:16: error: typedef redefinition with different types
('int' vs 'long')
typedef int ptrdiff_t;
Library/Developer/CommandLineTools/usr/lib/clang/9.1.0/include/stddef.h:51:26: note: previous definition is here
typedef __PTRDIFF_TYPE__ ptrdiff_t;
My understanding of the problem
There is a typedef collision between clang/9.1.0 and google-test on ptrdiff_t, where google includes regex.h which includes conda's own tclInt.h which has the typedef. tclInt.h is installed by the conda intel channel packages which we need. Uninstalling it downgrades mkl and tbb back various versions.
Here's a badly drawn dependency graph which shows where(I think) the typdef happened:
project native tests <-- googletest <-- regex.h <-- tclInt.h "typedef ptrdiff_t int;"
^
|
stddef.h "typedef ptrdiff_t long" (from clang)
I'm not quite sure how to approach this typedef collision problem and untangle it. One alternative is to use gcc-8, but even if I run make to build googletest with exported env vars:
CXX=g++-8
CC=gcc-8
the tclInt.h header is still pulled from the clang folder as indicated in the error dump I attached.
Ways to solve it (?)
There are definitely other options out there that I am missing, but a possible way to solve this is to have a tclInt.h that doesn't have this issue, or perhaps gcc-8 has a set of include headers that don't define ptrdiff_t, and there's something I can do to point to that compiler instead.
Note: I might be wildly wrong, but this is my hypothesis. Any help is appreciated.
If anyone wants to see the entire stacktrace, here you go:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-all.cc:39:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/gtest.h:58:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/internal/gtest-internal.h:39:
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/include/gtest/internal/gtest-port.h:452:
In file included from /foo/anaconda3/envs/idp3/include/regex.h:4:
/foo/anaconda3/envs/idp3/include/tclInt.h:60:16: error: typedef redefinition with different types ('int' vs 'long')
typedef int ptrdiff_t;
^
/Library/Developer/CommandLineTools/usr/lib/clang/9.1.0/include/stddef.h:51:26: note: previous definition is here
typedef __PTRDIFF_TYPE__ ptrdiff_t;
^
In file included from /foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-all.cc:45:
/foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-port.cc:597:10: error: use of undeclared identifier 'regexec'
return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
^
/foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-port.cc:606:10: error: use of undeclared identifier 'regexec'
return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
^
/foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-port.cc:619:15: error: use of undeclared identifier 'regcomp'
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
^
/foo/home/bar/native/build/gradle_unittest_build/googletest-src/googletest/src/gtest-port.cc:630:17: error: use of undeclared identifier 'regcomp'
is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
^
5 errors generated.
Typically, the Tcl header file <tclInt.h> has preprocessor conditions which determine whether ptrdiff_t should be defined or <stddef.h> should be included:
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
|| defined(__cplusplus) || defined(_MSC_VER)
#include <stddef.h>
#else
typedef int ptrdiff_t;
#endif
However, Intel has patched this in their tcl-8.6.4-19.tar.bz2 distribution file to:
#ifdef STDC_HEADERS
#include <stddef.h>
#else
#ifdef __ICC
# ifndef _PTRDIFF_T
# define _PTRDIFF_T
typedef int ptrdiff_t;
# endif
#else
typedef int ptrdiff_t;
#endif
#endif
Probably they thought they had to do something about the _MSC_VER dependency, although it is harmless in this context. This works with ICC because <stddef.h> is provided by the compiler, and their version of the header appears to check for the _PTRDIFF_T macro before defining it.
Normally, this is not visible because when using tclInt.h, you are supposed to use the compiler flags provided by tclConfig.sh, which define STDC_HEADERS, so <stddef.h> is used unconditionally.
But the use of Tcl here appears entirely accidental because Intel's Tcl distribution includes a regex.h header which overrides the system <regex.h> header, and this is what googletest wants to include here. Use of the wrong header file can lead to other problems, too. (This is why other distributions install the Tcl headers in directories such as /usr/include/tcl8.6 and even put the internal headers like regex.h into a separate subdirectory.)
I would try to deinstall the Tcl distribution from the build environment. Hopefully it is not really needed, and so the header file collision goes away.

Using OpenBLAS LAPACKE in Visual Studio

i need some linear algebra in my project and want use OpenBLAS for this. I downloaded the precompiled version (64bit version) and unpacked it to my projectfolder. In Visual Studio, i added include-, bin-, and lib-folder to my Project and ran the this example without problems.
Next, i wanted to look at LAPACK, so i added lapacke.h to the includes, which is in the same directory as cblas.h and is included in the official download. But now i get hundreds of errors, for every function, as if a lib file was missing or something. E.g. for this line
85 lapack_complex_float lapack_make_complex_float( float re, float im );
i get
PATH\include\lapacke.h(85): error C2146: syntax error: missing ';' before identifier 'lapack_make_complex_float'
I can't find any further information on how to set up OpenBLAS/LAPACK, they usually just say 'include the files', which i have. Otherwise the cblas example wouldn't run either. And the (relevant) examples i can find only use cblas.h, not lapacke.h
Can some tell me what i'm doing wrong?
The problem is that OpenBlas uses C99 _Complex by default. This is not supported by Visual C++. You can solve this by using standard library definitions before including lapacke.h:
#include <complex>
#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>
#include <lapacke.h>
Using std::complex is problematic unless OpenBLAS was built with LAPACK_COMPLEX_CPP otherwise the library uses a different complex type internally, usually C99 _Complex.
Modern versions of the Microsoft compiler (e.g. the one in VSTUDIO 2022) support a similar "_Complex" mechanism. Therefore I include the following header file prior to "lapacke.h"
#ifdef _MSC_VER
#include <complex.h>
#define LAPACK_COMPLEX_CUSTOM
typedef _Dcomplex lapack_complex_float;
typedef _Fcomplex lapack_complex_double;
#define lapack_complex_float_real(z) (real(z))
#define lapack_complex_float_imag(z) (imag(z))
#endif // _MSC_VER
See the lapack.h header file that ships with OpenBLAS how #define LAPACK_COMPLEX_CUSTOM overrides complex variable type definitions

Error C2371 'DWORD': redefinition; different basic types

I am getting this error "Error C2371 'DWORD': redefinition; different basic types" while compiling a Visual C++ code on Visual Studio 2015 using MFC.
When I double click the error it takes me to stdint.h line 23:
typedef unsigned int uint32_t;
And if I find any DWORD on my code and press f12 on it it takes me to minwindef.h line 156:
typedef unsigned long DWORD;
I am not explicitly including any of those file, so I don't know in which order those files are being included.
I am quite lost here on what to do to fix this error. Does anyone have a clue?
If you need more info please ask me.
I found the error, it was on a 3rdpartyapi.h:
#ifndef uint32_t
# define uint32_t DWORD
#endif
What I did was just include #include <cstdint> prior to the #ifndef and the error is gone.
Thank you all for the help.

Weird compile error dealing with Winnt.h

When trying to compile a file that include winnt.h via windows.h, I get the following error:
MyGl.cpp
..\microsoft sdks\windows\v6.0a\include\winnt.h(964) : error C2988: unrecognizable template declaration/definition
..\microsoft sdks\windows\v6.0a\include\winnt.h(964) : error C2059: syntax error : '&'
They point to the following lines in Winnt.h
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
Any ideas for what's going on?
My compiler:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
There are at least two ways to do this. The first is to simply include windows.h at the top of all your files. Then include winnt.h only if you need it. However, I find this a bit too much - I don't see the need of including all this goo in every single file.
What I do is this at the very top (first thing) in my C/C++ header files.
#ifndef __wtypes_h__
#include <wtypes.h>
#endif
#ifndef __WINDEF_
#include <windef.h>
#endif
This will get you you the data types, defines, and fundamental Windows API's. You may also need to add the following:
#ifndef _WINUSER_
#include <winuser.h>
#endif
#ifndef __RPC_H__
#include <rpc.h>
#endif
WinNT is a bit of a special animal - don't include it if including the above files works for you. If you do need it, include it after wtypes.h and `windef.h'
If this doesn't work, then check your include paths and predefined macros to see if those might be breaking your build.
Regards, Foredecker