根据CPPReference,#if
后面跟着一个常量表达式。sizeof
是常量表达式中的有效运算符。但是当我写这个并用 clang 或 gcc 编译它时,它失败了:
#if sizeof(char) == 1
#endif
铿锵的输出:
sizeof in preprocessor directive.c:1:5: error: function-like macro 'sizeof' is not defined
#if sizeof(char) == 1
^
1 error generated.
海湾合作委员会的输出:
sizeof in preprocessor directive.c:1:11: error: missing binary operator before token "("
1 | #if sizeof(char) == 1
| ^
是 CPPReference 错误还是编译器错误?
它们都是正确的,您似乎误解了 cppreference 所说的内容。
来自标准草案(N3096)6.10.1,有条件包含:
(强调我的)
这意味着从预处理器的角度来看,在 的上下文中
#if
,sizeof(char)==1
简单地替换为生成0(0)==1
,因为这不是有效的常量表达式,程序格式错误,编译器应该发出诊断,而编译器实际上会执行此操作并且是因此符合。sizeof
这里一点也不特别,也不是char
。它们就像任何其他尚未被#defined
, 替换的标识符一样。您可以通过诸如#if sizeof *1
,#if char+1
等内容自行测试。cppreference 引用没有错误。从你的链接来看,完整的句子是
这基本上与标准中的内容相同,并且它当然并不意味着您似乎认为“可以在此处使用任何常量表达式”。
我想以上应该已经足以回答你的问题了。只是为了更清楚地表明,代码不可能像您期望的那样工作,正如评论指出的那样,处理发生
sizeof
在翻译的第 7 阶段,距离预处理的最后一个阶段,即第 4 阶段很久之后。非正式地,我只想假设这sizeof
是由编译器处理的,而预处理器对此一无所知。无论你怎么说,在一个条件下都不可能sizeof(char)==1
评估为真#if
。CPPReference 缺少将具有标识符形式的关键字处理为标识符而不是关键字来处理常量表达式的精度。这种精度已经存在于 C89 中。