Generating an error if checked boolean macro is no

2020-02-27 10:54发布

问题:

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.

回答1:

Colleagues (hi Hartmut, Kurt) who maintained a large code base which was extensively configured with #defines 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 #ifdefs.



回答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.



回答3:

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.



回答4:

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.

.

.

.



标签: c++ c gcc macros