Answers:
在对所有定义的和__has_include(自C ++ 17起)的表达式进行宏扩展和求值后,所有不是布尔文字的标识符都将替换为数字``0''(这包括按词法命名的标识符,但不包括诸如和)。
因此,无论foo
和bar
0代替。
这是因为既foo
没有bar
给出也没有给出任何定义或值-因此它们是相同的(即用“ 0”值代替)。编译器将对此发出警告。
该MSVC
编译器(Visual Studio的2019)给出了以下情况:
警告C4668:未将'foo'定义为预处理器宏,将'
#if /#elif'替换为'0' 警告C4668:未将'bar'定义为预处理器宏,并将其## if /#elif 替换为'0' /#elif'
因此VALUE
,给定值'0'(默认为foo
),并且bar
也为'0',因此VALUE == bar
求值为“ TRUE”。
同样,clang-cl
给出以下内容:
警告:未定义'foo',其值为0 [-Wundef]
警告:未定义'bar',其值为0 [-Wundef]
MSVC
和clang-cl
编译器,也可以禁用此警告(具体而言,或通过设置适当的警告“级别”)。
要完成您想要的工作,请尝试以下操作:
#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中查阅“防御性编程”一章的“代码完成”。