我从N1570 C11草案(强调我的)中理解5.1.1.3/1 诊断子句的语义有些困难:
如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 - 定义.在其他情况下不需要产生诊断消息.9
我理解的意图是排除(非约束)未定义的行为(因此对例如缓冲区溢出没有诊断),但是#error指令呢?与6.10.5/1 Error指令一样:
表单的预处理指令
# errorpp-tokens 选择新线使实现生成包含指定序列的预处理标记的诊断消息.
这两个子条款是否相互排斥?
对于其他参考,请参阅DR#176.
小智 4
C99 比针对该 DR 的建议解决方案更进一步。他们不需要进行诊断,而是将其视为错误。
4. 一致性
4 实现不应成功翻译包含
#error预处理指令的预处理翻译单元,除非它是通过条件包含跳过的组的一部分。
现在,严格来说,也许您是对的,实现可以选择拒绝编译包含#error指令的程序而不发出诊断,声称 5.1.1.3 允许它忽略 的语义#error。然而,在标准设置的范围内达到尽可能无用的实现,可以轻松解决任何需要诊断的尝试:该实现可以简单地转储完整的预处理器输出(包括以下任何内容#error),并且接下来是“某处有错误”。因此,该标准是否需要诊断实际上并不重要。实施没有理由不这样做,而且该标准也无法强迫不情愿的实施者这样做。