"#if Foo - 0 == 0" 和 "#if defined(Foo) && Foo == 0" 有什么区别?(涉及IT技术)

12
qt文档中可以找到这个内容。

有什么区别?

#if defined(Foo) && Foo ==  0

并且

#if Foo - 0 ==  0

据我所知,如果Foo未定义,后者也将是false。我在哪里可以阅读相关信息?
2个回答

20
如果 Foo 未定义,则后者将转换为

#if 0 - 0 == 0

这是真的,而不是假的。请记住,在#if下,所有未定义的标识符都将替换为文字0(在求值所有defined()运算符之后,当然)。即使是匹配语言关键字的预处理标记也是如此。在C语言中,所有关键字在此上下文中都被替换为0。在C ++中,关键字truefalse是例外,而所有其他关键字都将被替换。

顺便说一句,在C中,如果未包括<stdbool.h>,则true将被静默地替换为0,如果已包括,则将被替换为1

同时

#if defined(Foo) && Foo == 0

Foo未定义时,结果为假。因此,这就是它们之间的区别。

Qt文档确实似乎暗示前者与后者相同。我不知道他们为什么这样做,因为它们肯定不等价。这似乎是Qt文档中的一个错误。


所以在Qt文档中有一个错误!因为从他们的解释中得出这两个是相等的。 - Hate
5
+1 表示若有任何未定义的标识符将被替换为字面量 0。 - billz
@billz和AndreyT,你们能分享一些关于C++宏的链接或建议文章吗?因为我找到的只是它们的列表和简要描述,但我肯定没有在任何地方读到过像“所有未定义的标识符都被替换为字面0”这样的东西。 - Hate
1
这是标准中实际的规则:“在宏展开和defined一元运算符引起的所有替换完成后,除了truefalse之外的所有剩余标识符和关键字都将被替换为pp-number 0,然后每个预处理记号都会转换为一个标记。”第16.1p4节。 - Ben Voigt
ISO/IEC 14882:2011(C++标准)§16.1条件包含说:¶4在评估之前,预处理令牌列表中的宏调用将成为控制常量表达式被替换(除了由defined一元运算符修改的那些宏名称),就像在普通文本中一样。[...]在执行了由于宏展开和defined一元操作符而进行的所有替换之后,除了true和false之外的所有剩余标识符和关键字都将替换为pp-number 0,然后每个预处理令牌都转换为一个令牌。 - Jonathan Leffler

1

Foo == 0 和 Foo - 0 == 0 的区别在于,在前者中,Foo 必须定义一个值:

#define Foo 0

并且不能是:

#define Foo  //  Foo == 0 would give an error, cannot evaluate Foo

在Foo - 0 == 0的情况下,Foo可以被定义为没有值

因此:

#if defined(Foo) && Foo ==  0

Means Foo已被定义并且它有一个值(在这种情况下为0)。

以及:

#if Foo - 0 ==  0

意味着Foo要么被定义为0,要么没有被定义任何值,但由于它不像第一种情况中那样有defined(Foo)的定义,因此未定义的Foo也适用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接