Do 'true' and 'false' have their usual meaning in preprocessor conditionals?
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.
According to [cpp.cond]/4 in the C++11 standard:
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the
defined
unary operator), just as in normal text. […] After all replacements due to macro expansion and thedefined
unary operator have been performed, all remaining identifiers and keywords, except fortrue
andfalse
, are replaced with the pp-number0
, and then each preprocessing token is converted into a token. The resulting tokens comprise the controlling constant expression which is evaluated according to the rules of [expr.const] using arithmetic that has at least the ranges specified in [support.limits]. […] Each subexpression with typebool
is subjected to integral promotion before processing continues.
Emphasis mine; from the bolded passages it follows that bool
-typed expressions are meant to be supported in preprocessor conditions just like in the language proper, including bool
literals true
and false
. The [expr.const] section defining constant expressions is referred to from other sections that use it in non-preprocessing context, from which it follows that the evaluation rules are the same in the preprocessor and the language proper.
I’d assume similar language appears in all further revisions of the C++ standard, and probably in earlier ones too. In C, on the other hand, true
and false
are not keywords, but macros defined in stdbool.h
, so the preprocessor treats them just like any other token.
The usual practice is to use 1
and 0
for logical values in preprocessor expressions for maximum portability, and preferably to avoid directly referring to them entirely.