Trying to fix the following "macro redefinition" warning:
1>Path\to\MKL\include\math.h(1577): warning C4005: 'HUGE_VALF' : macro redefinition
1> Path\to\Microsoft Visual Studio 12.0\VC\include\../../vc/include/math.h(104) : see previous definition of 'HUGE_VALF'
Generated from this code:
#include "ABC/CUDA_FFT.h"
#include "ABC/logging.h"
#include "Utilities/Utils.h"
#pragma warning( push )
#pragma warning( disable : 4005 ) // macro redefinition (no effect)
#include <cufft.h>
#include <cuda_runtime.h>
#pragma warning( pop )
#include <complex>
The HUGE_VALF macro is defined in both included files.
I tried to #undef HUGE_VALF before including any of the above headers, but I still got the same warnings.
Since I have to use both Intel and Microsoft maths libraries, how can I prevent this warning from being generated?
If you really have to use two libraries with overlapping identifier names (poor you, I feel with you) then the only clean way is to use them from separated .c files.
I.e. make one .c file which includes the header for one lib and a second .c file which includes the header of the other lib.
Problems with overlapping macro definitions should be solved this way.
If you additionally have overlapping linker identifiers (function names, global variable names...), then it will be necessary to link the two code files separatly to the corresponding libs.
The real trouble starts if you then have to use functionalities from both libs in one function written by you. That will require to first wrap the two functionalities in uniquely named functions in the corresponding code files, which then can be unambigously called from another code file to use both.
Do not try to solve your problem with #undef, that is just a way to risk (or, according to murphy law, guarantee) that the wrong definition of overlapping macro names will be used unexpectedly.
In short, if you think that #undef could help you, then your problem is larger than you are aware of.
This might seem cynical, please understand that I only try to let you benefit from some serious scorch-mark experiences I made. Debugging in the presence of uncleanly overlapping symbols will get you singed. As I have mentioned in my profile, I learned to supersticiously consider #undef to be unlucky.
But, to also answer the actual question you wrote, to get rid of the "redefinition" symptom (not the problem, mind) you need to do the #undef BETWEEN the two includes, not before. That way the first include defines the problematic macro. Then it gets undefined. Then the second include defines it again, without seeing it already being defined.
Related
For the long time, standard libraries were giving me headache by throwing compilation errors simply by including them. For the long time, I've gone around it by reimplementing the parts that I needed, or with some #define for cstdio.
Now I need to include the library, and I don't really see any ways around it. Yet again, I see no way of doing it either - any clues of dealing with that? I have tried the following:
#ifndef _CRT_FUNCTIONS_REQUIRED
#define _CRT_FUNCTIONS_REQUIRED 1
#endif // !_CRT_FUNCTIONS_REQUIRED
#include <thread>
And a few such variations, but to no avail.
EDIT - fixed:
I had created a "Math.h" header, breaking any headers relying on the standard C++ library "math.h". After renaming the header (and it's references) the code compiled.
I had created a Math.h header file. Renaming it fixed the problem.
It appears to be a good idea to avoid using file names from the C++ standard library, who would've said it.
So I'm currently working on something that uses OpenCL. The OpenCL spec provides the users with a directive which must be included before the inclusion of the header (cl.h)
#define CL_TARGET_OPENCL_VERSION 110
Which basically defines the version they want to use. Suppose I'm making a library and I want my users to define this instead of me defining this inside my files. What I did was.
-----main.cpp---
#define CL_TARGET_OPENCL_VERSION 110
#include "library.h"
-------x---------
----library.h-----
#ifdef CL_TARGET_OPENCL_VERSION
#pragma message("def")
#endif
#ifndef CL_TARGET_OPENCL_VERSION
#pragma message("ndef")
#endif
.... include other headers.
--------x---------
And the compiler prints both def and ndef messages. And the OpenCL library also throws a warning that it's undefined. I thought that the library header would get substituted into main and it'd only print the def message. Is there anything I understood wrong?
I'm particularly confused as to where does the preprocessor start? If it starts from main.cpp and goes from top to down, then it surely has defined the macro. After that it sees the library inclusion, then it should only print the def message but it prints both.
This leds me to believe the preprocessor does scan the header file before including it in main? Dunno the reason why. Also I have assured that the library header isn't included elsewhere.
One interesting thing I noticed was, if i did this
-----helper.h---
#define CL_TARGET_OPENCL_VERSION 110
-------x---------
----library.h-----
#include helper.h
#ifdef CL_TARGET_OPENCL_VERSION
#pragma message("def")
#endif
#ifndef CL_TARGET_OPENCL_VERSION
#pragma message("ndef")
#endif
.... include other headers.
--------x---------
It prints the def message "twice". If anybody can explain all this I'd be grateful.
EDIT:- The files I'm compiling are main.cpp library.h and library.cpp
Library.cpp includes library.h from the start as usual. Maybe this other cpp is causing the problem?
In C/C++ programs, the compiler handles each .c and .cpp file separately.
The compilers build each source file (NOT the header files, only .c and .cpp files) independently from each other (this source files are called compilation unit).
Thus, when your main.cpp is built, the compiler finds the #define CL_TARGET_OPENCL_VERSION 110 you have added on top of the main.cpp file, emiting the defmessage.
But when the compiler builds the library.cpp file, it does not find the version define, so it emits the ndef message.
So, following this explanation, it is completely normal that in your last case, when you add the define to the .h file, the compiler emits the def message twice, once for the main.cpp file and once for the library.cpp file.
Now, the problem is where should you add the define, in order to have the program built consistently, with the same version for all the .cpp files.
Usually, all the IDEs have some configuration page where you can add global defines, for all the project, which are "inserted" into all the compilation units before everything else. So when the IDE calls the compiler, it passes the same defines to all the compilation units. You should add this kind of defines in this page.
In your IDE (I am using Code::Blocks, v 17.12), you can find this page in the menu: Project / Build Options
For each type (Debug or Release), you have to go to the tab Compiler Settings, and there to the sub tab #defines. There you can add global defines, which can be different if you are building in Debug or in Release mode (of course, if you set the same in both modes, they would be the same).
Once you have added your define here, please, remove it from the main.cpp, library.h and any other place where you may have added it, in order to avoid duplicities.
From the comments about portability:
You have several options:
Always use Code::Blocks: this would be the easiest way, since you can pass the Code::Blocks project along with the source files, and everything would be already setup.
Use cmake, which is a script build system, where you can set defines and so in the same way as using an IDE. cmake is much widely used than Code::Blocks, so maybe it is a better option.
Add a new options.h header file, where you set all the defines, and include it to all your .c/.cpp. This setup has the additional benefit that for different systems, changing only the options.h file the build can be completely different. This is a manually setup of what the IDE is doing. It has the advantage that does not rely on external tools, but the disadvantage that you have to remember to add it in all the new .cpp files added to the project.
My recommendation is go with cmake, just as the others have said.
Prefer using #ifndef XXXX_h #define XXXX_h #endif over #pragma once
If your #include search path is sufficiently complicated, the compiler may be unable to tell the difference between two headers with the same basename (e.g. a/foo.h and b/foo.h), so a #pragma once in one of them will suppress both. It may also be unable to tell that two different relative includes (e.g. #include "foo.h" and #include "../a/foo.h" refer to the same file, so #pragma once will fail to suppress a redundant include when it should have.
This also affects the compiler's ability to avoid rereading files with #ifndef guards, but that is just an optimization. With #ifndef guards, the compiler can safely read any file it isn't sure it has seen already; if it's wrong, it just has to do some extra work. As long as no two headers define the same guard macro, the code will compile as expected. And if two headers do define the same guard macro, the programmer can go in and change one of them.
#pragma once has no such safety net -- if the compiler is wrong about the identity of a header file, either way, the program will fail to compile. If you hit this bug, your only options are to stop using #pragma once, or to rename one of the headers. The names of headers are part of your API contract, so renaming is probably not an option.
(The short version of why this is problematic to use #pragma is that neither the Unix nor the Windows filesystem API offer any mechanism that guarantees to tell you whether two absolute pathnames refer to the same file.)
I'm having trouble with someone else's code, what seems to be header files included out of order. (E.g., I'm getting redefinition errors, some of which are even in the same file!) It would be useful to see the #include tree the C++Builder compiler is using, similar to Visual Studio's -showIncludes flag. Is there any such functionality; if so, how do I access it? I am specifically using C++Builder 2007.
This usually happens if you including multiple times files which contains global constants, variables and sometimes even #defines. This is very common for MDI apps where the master Form contains include of the child Forms and some of them use the same libs ...
The include hierarchy would not help for this unless you are planning to edit all source files #include order which can lead to problems later on (especially compatibility)...
To remedy this you should encapsulate all such files with
#ifndef _file_name_h
#define _file_name_h
// here your source and includes
#endif
statements. Like in this example:
OpenGL drawing a cube
That will prevent multiple definitions and compilations on pre-compiler level as the source will be processed only the first time (while #define _file_name_h is still not defined).
Sadly, there are no Borland C Compiler options for displaying the hierarchy of #included files. See Embarcadero's BCC32 CLI docs.
However, an alternative (granted, not as clean) is to use the Borland C Compiler Preprocessor, e.g.
CPP32 -Sr source.cpp # outputs source.i with comments and indentation retained
Using C++ Native solution in Visual Studio 2010.
#pragma warning (push) is used in the beginning of the cpp file, after all the includes. After that there are couple of disabled warning by #pragma warning(disable : XXXX).
What are possible consequences of omitting #pragma warning(pop) at the end of the file?
Thanks
If you have any other source files that #include that cpp file, then the warning state when compiling the outer file will be messed up -- it could fail to give warnings when the warnings were warranted.
Note, however, that #includeing a cpp file is considered bad form and a code smell; there are certain, rare, situations where it might be the right thing to do (such as a build system that #includes many source files into one to reduce compilation times, sort of like precompiled headers), but almost always it's the wrong thing to do, even if it manages to compile and link without errors.
If that source file is never #included anywhere else, then failing to have a #pragma warning(pop) will not have any adverse consequences, assuming the compiler doesn't complain about that mismatch in the first place.
Since this is a compiler only setting, it won't have any impact on the program itself. It may though screw up warnings for external includes.
Problem
In CodeGear C++Builder 2009 we are using the pre-compiled header injection to greatly reduce our compile times. We have the same header file being injected into multiple projects. When compiling some projects, the compiler kicks out the following warning:
[BCC32 Warning] Dateutils.hpp(43): W8058 Cannot create pre-compiled header: initialized data in header
In this example, the Dateutils.hpp is the file it's complaining about (CodeGear's header). I've seen this happen with other headers as well. What makes this interesting is that this only happens with some projects (same header being injected).
In the past, I've had to just find the header who ultimately included this errant file and remove it from my pre-compiled header file. Does anyone know what's going on here and the best way to fix it?
Update
I ended up performing a process of elimination approach to the header file and came up with an interesting finding that I cannot explain. Out of the 50+ headers that get included, when I removed vcl.h I no longer get the W8058 warnings. I do not understand this as I would imagine that this header file in particular is a prime candidate for pre-compiliation. Can anyone explain that?
One thing that may be related is the way default string parameters are handled by BCB 200x.
Functions declared like this give the "can't generate precompiled header" message.
void myFunc(const AnsiString ¶m="");
However, change it to this, and the precompiled header can be generated.
void myFunc(const AnsiString ¶m = AnsiString(""));
In my experience, that warning message is misleading. It seems that the compiler identifies "candidates" where a header might have initialized data, then when it determines that the file is actually ok, it goes on. If it doesn't find another candidate, it won't show the message. If it finds another candidate that turns out to be a real problem, it then shows the message about the first candidate.
This makes identifying the real culprit extremely difficult.
There are VCL header files that have this known issue: QC 23002. The marked severity on this item though is a "minor failure."
So the workaround options are limited:
Not using those header files (which, yes, does defeat the idea)
Modify the header files (not advisable -- hard to track changes, keep them current).
Either way, make sure that of the ones you come across, CodeGear has knowledge of those header files having that issue. That will certainly be the best way to address it long term -- let the vendor fix their problem. Supposedly CodeGear has DateUtils.hpp in their internal tests for this, but that was posted (for QC 2781) in July 2007. If the problem or certain header files affect you considerably, contact them about it.
I get this warning message when the code shows:
#include <vcl.h>
#pragma hdrstop
I found a simple fix by swapping these lines to:
#pragma hdrstop
#include <vcl.h>
Warning no longer appears.