C 中的宏比较结果不正确

Cur*_*ous 0 c

为什么以下代码的输出不是10预期的20

#define A double

#if A == float
    #define X 10
#elif A == double
    #define X 20
#endif

int main() {
    return X;
}
Run Code Online (Sandbox Code Playgroud)

尝试一下: https: //godbolt.org/z/r8xhq5Pja

Jon*_*ler 5

该标准规定,在预处理器条件中,宏扩展完成后剩下的任何标识符都被视为零。和floatdouble变为 0 \xe2\x80\x94 条件的结果是 因此#define X 10,程序返回10到环境。

\n

请参阅 (C11) \xc2\xa76.10.1 Conditional Inclusion,特别是 \xc2\xb64 (添加了重点):

\n
\n

\xc2\xb64 4 在求值之前,预处理标记列表中将成为控制常量表达式的宏调用将被替换(由一元运算符修改的宏名称除外defined),就像在普通文本中一样。defined如果由于此替换过程而生成标记,或者使用defined一元运算符与宏替换之前的两个指定形式之一不匹配,则行为未定义。在执行完所有由于宏扩展和定义的一元运算符引起的替换后,所有剩余的标识符(包括词法上与关键字相同的标识符)都被替换为 pp-number 0,然后将每个预处理标记转换为标记。生成的标记组成控制常量表达式,该表达式根据 6.6 的规则进行计算。出于此令牌转换和评估的目的,所有有符号整数类型和所有无符号整数类型的行为就好像它们分别具有与 header 中定义的类型intmax_t和相同的表示形式。167)这包括解释字符常量,这可能涉及将转义序列转换为执行字符集成员。这些字符常量的数值是否与表达式中(除or指令之外)中出现相同字符常量时获得的值匹配是实现定义的。168)此外,单字符字符常量是否可以具有负值是实现定义的。uintmax_t<stdint.h>#if#elif

\n
\n