问题
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