If I defined a macro:
#define FOO
And in the code I check it like:
#if FOO
//1
#else
//2
#endif
Which branch will it go? Will the result be different by different compilers? What is the FOO
value in the #if FOO
?
C17 6.10.1 specifies the syntax for #if
as:
# if
constant-expression new-line groupopt
Where:
1
(integer constant) or 1+1
(integer constant expression), or a preprocessor token expanding to such.#if
line.#if
and #endif
etc.6.10.1 further states that macro expansion inside #if
is done as:
After all replacements due to macro expansion and the
defined
unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number0
, and then each preprocessing token is converted into a token. The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6.
Meaning that if some token after #if
is not a known preprocessor token, it gets replaced with 0
. The reference at the end to 6.6 refers to the chapter defining a constant expression.
Conclusion: if FOO
is defined and a known pre-processor token, it will get expanded but the macro is empty in this case. The #if
will end up missing a constant expression, since that mandatory part of the syntax is not present before the new line. Meaning we get a syntax error - it is invalid C and will not compile without compiler diagnostics getting raised (see What must a C compiler do when it finds an error?).
However, if FOO
was unknown either because it was misspelled or missing, or simply because it was defined in another translation unit unknown to the current one, it will get replaced with 0
and the #if
will evaluate as false.
Note that defines that are passed to the program using compiler options such as for example gcc -D
may have a default value applied to them. For gcc and clang, that value is 1. https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
-D name
Predefine name as a macro, with definition 1.