考虑以下代码,这会导致在预处理器条件中评估布尔文字true
:
#define SOME_MACRO true
int main ()
{
#if SOME_MACRO
return 1;
#else
return 0;
#endif
}
Clang 3.4和GCC 4.8都接受此代码,即使使用-pedantic -std=c++11 -Wall -Wextra
。
Visual Studio 2013使用fatal error C1017: invalid integer constant expression拒绝它。
我阅读n3376§ 16.1是用于评估常量表达式的常规C ++规则应该适用。
如果是这样,这段代码是有效的,如果MSVC不接受它,那就是一个错误。
但我没有发现标准特别清楚。有人可以证实这一点吗?
答案 0 :(得分:8)
是的,它是有效的。参见C ++11§16.1/ 4(强调我的)
在评估之前,预处理令牌列表中的宏调用将成为控制 替换常量表达式(
defined
一元运算符修改的宏名称除外), 就像在普通文本中一样。如果由于此替换过程或使用而生成令牌defined
在宏替换之前,defined
一元运算符与两个指定表单中的一个不匹配, 行为未定义。在由于宏扩展和defined
一元运算符导致的所有替换之后 已执行,所有剩余的标识符和关键字(true
和false
除外)均已替换 使用pp-number0
,然后将每个预处理令牌转换为令牌。由此产生的代币 包括控制常数表达式,其使用算术根据5.19的规则评估 至少具有18.3中规定的范围。出于此令牌转换和评估的目的 有符号和无符号整数类型的行为就像它们分别具有相同的表示形式intmax_t
或uintmax_t
(18.4)。这包括解释字符文字,这可能涉及转换转义 序列成执行字符集成员。是否为这些字符文字的数值 匹配在表达式中出现相同字符文字时获得的值(除了a之外)#if
或#elif
指令)是实现定义的。此外,是否可以使用单字符字符文字 具有负值是实现定义的。 每个类型为bool
的子表达式都是积分的 处理前的促销活动继续进行。