Given a C++11 compiler, which #error
is the correct one it should end up with?
// no #includes!
#define SOMEMACRO true
#if SOMEMACRO
#error "it was true"
#else
#error "it was false"
#endif
Obviously I'm using #error
just as a test. I know true
and false
are defined in the language proper, but this is preprocessor context. In C99 it seems not to be recognised by the preprocessor.
I'm asking because it seems that all compilers I tried see it as 'true', while a static code analysis tool insists that true
isn't defined, implicitly false and ends up in "it was false".
In all ISO C++ standards, both true
and false
are keyword constants, just like nullptr
in C++11. So #if SOMEMACRO
= #if true
and the preprocessor will go to the truthy branch.
In C, however, neither true
nor false
is ever a keyword. They're macros defined to 1
and 0
respectively, as of C99 and with #include <stdbool.h>
. This does mean that however, if you don't include stdbool.h
, the compiler should complain about unrecognized identifiers for true
, false
etc. After including the header, #if SOMEMACRO
is now #if 1
, which is truthy in C.
For preprocessing, this quote from CppReference is meaningful:
Any identifier, which is not literal, non defined using
#define
directive, evaluates to 0.
So in your (probably C-oriented) static analysis tool, it sees true
as a non-#define
-defined identifier, and therefore evaluates true
to zero. You're not going to observe this behavior if you use a C++ analysis tool.
In that case, you probably shouldn't have missed the #include <stdbool.h>
in the first place, though.