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 deci
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.
.
.
.
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.
Macro CHECK(x)
will:
x
is undefined,00
if x
is defined to 0
01
if x
is defined to 1
$ cat main.cpp
#define CAT(x, y) x##y
#define CHECK(x) CAT(0, x)
// usage
#define COND0 0
#define COND1 1
#if CHECK(COND)
#endif
#if CHECK(COND0)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
#if CHECK(COND1)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
$ g++ main.cpp
main.cpp:9:1: error: user-defined literal in preprocessor expression
9 | #if CHECK(COND)
| ^~~~~
main.cpp:15:17: note: ‘#pragma message: defined 0’
15 | #pragma message "defined 0"
| ^~~~~~~~~~~
main.cpp:19:17: note: ‘#pragma message: defined 1’
19 | #pragma message "defined 1"
| ^~~~~~~~~~~
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.