如果指令宏比较


25

为什么#if以下代码中的条件得到满足:

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}

Answers:


26

cppreference.com上页面指出:

在对所有定义的和__has_include(自C ++ 17起)的表达式进行宏扩展和求值后,所有不是布尔文字的标识符都将替换为数字``0''(这包括按词法命名的标识符,但不包括诸如和)。

因此,无论foobar0代替。


C ++ 98,C ++ 03,C ++ 11和C ++ 14呢?
kelalaka

1
@kelalaka都是一样的。自C89以来就是这样。
SS安妮

1
@kelalaka“自C ++ 17起”仅指“和__has_include”部分。在C ++ 17之前是相同的,只是省略了该部分。
BessieTheCow

15

在一条#if语句中,宏替换后剩下的任何标识符(true和除外false)都将被常量替换0。所以你的指令变成

#if 0 == 0

没错


为了澄清,“VALUE的#define富”定义符号“价值”的决心,同样的值作为符号“富”,但是符号“富”是没有意义的,所以它会被解释为0
ManicDee

13

这是因为既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]


警告是强制性的还是编译器的功能?
kelalaka

1
据我所知,@ kelalaka不需要编译器“警告”!即使使用MSVCclang-cl编译器,也可以禁用此警告(具体而言,或通过设置适当的警告“级别”)。
阿德里安·摩尔

0

要完成您想要的工作,请尝试以下操作:

#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中查阅“防御性编程”一章的“代码完成”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.