I have several configuration files each one containing the definition of some boolean macro, to be set to 0 or 1. Then, in my code, I check the value of such a macro to decide which part of the code to activate. Now comes the tricky part: I want to be sure that the header containing the definition of my macro has been included.
In the following example, if I forget to include the header file containing FOO definition, the compiler will print "world!", while I would like instead that it generated an error.
//in the configuration header file
#define FOO 1
//in a cpp file
#if FOO //I would like this to generate an error if I forgot to include the header file
#pragma message "Hello"
#else
#pragma message "world!"
#endif
Is it possible to achieve such a behaviour? How?
To clarify, I am not asking how to generate an error if a macro is not defined, but if it is possible to transform the #if FOO
line so that, at the same time, it checks the boolean value and generates an error if FOO
is not defined.
The point of having this would be that developers would know that their code should contain
SPECIAL_MACRO(FOO)
which, at the same time, check the boolean value of FOO as if it was an #if FOO
statement, and prevents them from forgetting the inclusion of the header defining FOO
.
Colleagues (hi Hartmut, Kurt) who maintained a large code base which was extensively configured with #define
s ran exactly into the same problem. A simple mis-spelling, possibly in a make file, could result in subtle errors which were hard to track down. Their solution: Use function macros! In
#if SOME_COND()
// ...
#endif
the compiler complains if SOME_COND() is not defined, as opposed to a simple SOME_COND which will be replaced by 0 if undefined. I like it because it can be used to transport several values without cluttering the code up with additional #ifdef
s.
The accepted answer of using function-macros is good, but if you want to keep normal macros - and still use the value of FOO if defined and generate an error otherwise you could do:
#if FOO / defined(FOO)
#else
#endif
If FOO
is not defined it will trigger integer division by zero.
What about using the -Wundef
gcc preprocessor option? This will only generate a warning, which can easily be turned to an error with -Werror=undef
.
I think can solve your problem in simple tricky solution. I change your code as below and my code understand that header.h doesn't exist and show error to me.
#if FOO == 1
#pragma message "Hello"
#elif FOO == 2
#pragma message "world!"
#else
throw std::invalid_argument("Header didn't add to project");
#endif
only you need to change your initial value for Foo.
because compiler activate Foo==0 when it doesn't find FOO, you shouldn't use 0 value for your configuration. you should leave zero for header absence situation.instead you must use values greater than zero(1 , 2, 3 , ...).
Foo==0 absence situation.
Foo==1 Configuration 1.
Foo==2 Configuration 2.
.
.
.