if-指令宏比较

mic*_*t38 27 c++ c-preprocessor

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

#include <iostream>
#define VALUE foo    

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

Ale*_*ang 28

cppreference.com 上页面指出:

在定义和 __has_include (C++17 起)表达式的所有宏扩展和求值之后,任何不是布尔文字的标识符都被替换为数字 ?0? (这包括作为词法关键字的标识符,但不包括和这样的替代标记)。

所以VALUE首先用替换foo,然后都foobar0代替。

  • @kelalaka“自C ++ 17以来”仅指“和__has_include”部分。在 C++17 之前,情况是一样的,只是省略了该部分。 (2认同)

Adr*_*ica 17

这是因为既foo没有bar也没有给出任何定义或值 - 所以它们是相同的(即替换为“0”值)。编译器会对此发出警告。

MSVC编译器(Visual Studio的2019)给出了以下情况:

警告 C4668:“foo”未定义为预处理器宏,“#if/#elif”用“0”代替
警告 C4668:“bar”未定义为预处理器宏,“#if”用“0”代替/#elif'

SoVALUE被赋予值“0”(默认为foo)并且bar也有“0”,所以VALUE == bar计算结果为“TRUE”。

同样,clang-cl给出以下内容:

警告:'foo' 未定义,计算结果为 0 [-Wundef]
警告:'bar' 未定义,计算结果为 0 [-Wundef]


120*_*arm 16

#if语句中,宏替换后剩余的任何标识符(除了truefalse)都将替换为常量0。所以你的指令变成

#if 0 == 0
Run Code Online (Sandbox Code Playgroud)

这是真的。