【发布时间】:2011-07-02 09:45:07
【问题描述】:
为了评估 #if 条件,我的预处理器似乎假定未定义的常量为 0。
这可以依赖,还是未定义的常量会给出未定义的行为?
【问题讨论】:
标签: c++ c-preprocessor
为了评估 #if 条件,我的预处理器似乎假定未定义的常量为 0。
这可以依赖,还是未定义的常量会给出未定义的行为?
【问题讨论】:
标签: c++ c-preprocessor
OP 专门询问了 C 预处理器,第一个答案是正确地引用了 C 预处理器规范。但是其他一些 cmets 似乎模糊了 C 预处理器和 C 编译器之间的区别。需要明确的是,这是两个不同的东西,有不同的规则,它们在两个不同的通道中应用。
#if 0 == NAME_UNDEFINED
int foo = NAME_UNDEFINED;
#endif
此示例将成功输出 foo 定义,因为 C 预处理器将 NAME_UNDEFINED 作为条件表达式的一部分计算为 0,但生成编译器错误,因为初始化器未作为条件表达式计算,然后 C 编译器将其计算为一个未定义的符号。
【讨论】:
是的,可以信赖。 C99 标准在 §6.10.1 ¶3 中指定:
由于宏扩展和定义的一元的所有替换 运算符已执行,所有剩余的标识符都替换为 pp 号
0
编辑
对不起,我以为是 C 题;不过,没什么大不了的,C++ 标准(§16.1 ¶4)中的等效部分指出:
由于宏扩展和定义的一元运算符的所有替换 已执行,所有剩余的标识符和关键字,除了
true和false,都替换为pp 编号0
唯一的区别是true和false的处理方式不同,在C中不需要特殊处理,而在C++中即使在预处理阶段它们也有特殊含义。
【讨论】:
未定义为宏的标识符在计算表达式之前转换为0。
例外是标识符true,它被转换为1。这是特定于 C++ 预处理器的;在 C 中,这不会发生,您需要包含 <stdbool.h> 才能以这种方式使用 true,在这种情况下,它将被定义为宏并且不需要特殊处理。
【讨论】:
true 是关键字而不是宏——它的解释与预处理器无关,因此也不例外。
#if whatever == true 之类的预处理器指令中使用true,则whatever 和true 都是普通标识符。预处理器有自己的语言,所以需要特殊的大小写。