问题
Why is the #if
condition in the following code fulfilled:
#include <iostream>
#define VALUE foo
int main() {
#if VALUE == bar
std::cout << "WORKS!" << std::endl;
#endif // VALUE
}
回答1:
The page on cppreference.com states:
After all macro expansion and evaluation of defined and __has_include (since C++17) expressions, any identifier which is not a boolean literal is replaced with the number 0 (this includes identifiers that are lexically keywords, but not alternative tokens like and).
So VALUE
is first replaced with foo
, and then both foo
and bar
are replaced with 0.
回答2:
This is because neither foo
nor bar
have been given any definition or value - so they are the same (i.e. replaced with a "0" value). Compilers will give warnings about this.
The MSVC
compiler (Visual Studio 2019) gives the following:
warning C4668: 'foo' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
warning C4668: 'bar' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
So VALUE
is given the value '0' (default for foo
) and bar
also has '0', so VALUE == bar
evaluates to "TRUE."
Similarly, clang-cl
gives the following:
warning : 'foo' is not defined, evaluates to 0 [-Wundef]
warning : 'bar' is not defined, evaluates to 0 [-Wundef]
回答3:
In a #if
statement, any identifier that remains after macro substitution (except for true
and false
) are replaced with the constant 0
. So your directive becomes
#if 0 == 0
which is true.
回答4:
To accomplish what you are after, try this:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
In this case you can turn the debugging statements off by changing the "define" to "undef".
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
You might find that your compiler allows you to define DEBUG outside the code itself, at which point you can reduce the code to
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
And then invoke the compiler with an option such as -DDEBUG=0
Check out the chapter on Defensive Programming in Steve McConnell, "Code Complete."
来源:https://stackoverflow.com/questions/60779032/if-directive-macro-comparison