If指令宏比较
If-directive macro comparison
为什么下面代码中的#if
条件成立:
#include <iostream>
#define VALUE foo
int main() {
#if VALUE == bar
std::cout << "WORKS!" << std::endl;
#endif // VALUE
}
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).
所以VALUE
先替换成foo
,然后foo
和bar
都替换成0.
在 #if
语句中,宏替换后剩余的任何标识符(true
和 false
除外)都将替换为常量 0
。所以你的指令变成
#if 0 == 0
这是真的。
这是因为 foo
和 bar
都没有被赋予任何定义或值 - 所以它们是相同的(即替换为“0”值)。编译器将对此发出警告。
MSVC
编译器(Visual Studio 2019)给出以下内容:
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'
所以 VALUE
被赋予值 '0'(foo
的默认值)并且 bar
也有 '0',所以 VALUE == bar
计算为 "TRUE."
类似地,clang-cl
给出以下内容:
warning : 'foo' is not defined, evaluates to 0 [-Wundef]
warning
: 'bar' is not defined, evaluates to 0 [-Wundef]
要完成你想要的,试试这个:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
在这种情况下,您可以通过将 "define" 更改为 "undef" 来关闭调试语句。
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
您可能会发现您的编译器允许您在代码本身之外定义 DEBUG,此时您可以将代码缩减为
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
然后使用 -DDEBUG=0
等选项调用编译器
查看 Steve McConnell 的防御性编程一章,"Code Complete."
为什么下面代码中的#if
条件成立:
#include <iostream>
#define VALUE foo
int main() {
#if VALUE == bar
std::cout << "WORKS!" << std::endl;
#endif // VALUE
}
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).
所以VALUE
先替换成foo
,然后foo
和bar
都替换成0.
在 #if
语句中,宏替换后剩余的任何标识符(true
和 false
除外)都将替换为常量 0
。所以你的指令变成
#if 0 == 0
这是真的。
这是因为 foo
和 bar
都没有被赋予任何定义或值 - 所以它们是相同的(即替换为“0”值)。编译器将对此发出警告。
MSVC
编译器(Visual Studio 2019)给出以下内容:
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'
所以 VALUE
被赋予值 '0'(foo
的默认值)并且 bar
也有 '0',所以 VALUE == bar
计算为 "TRUE."
类似地,clang-cl
给出以下内容:
warning : 'foo' is not defined, evaluates to 0 [-Wundef]
warning : 'bar' is not defined, evaluates to 0 [-Wundef]
要完成你想要的,试试这个:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
在这种情况下,您可以通过将 "define" 更改为 "undef" 来关闭调试语句。
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
您可能会发现您的编译器允许您在代码本身之外定义 DEBUG,此时您可以将代码缩减为
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
然后使用 -DDEBUG=0
等选项调用编译器查看 Steve McConnell 的防御性编程一章,"Code Complete."