我无法理解N1570 C11草案中的5.1.1.3/1
诊断子句的语义(强调我的):
如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现定义。 无需在其他情况下生成诊断消息。 9
据我所知,目的是排除(非约束)未定义的行为(因此对例如缓冲区溢出没有诊断),但是#error
指令呢?与在6.10.5/1
错误指令中一样:
表单
的预处理指令
# error
pp-tokens opt new-line导致实现生成诊断消息,其中包含指定的预处理标记序列。
这两个子条款是否相互排斥?
对于其他参考,请参阅DR#176。
答案 0 :(得分:4)
作为在委员会任职的人,我们对这样一个问题的回答通常都是以“仔细阅读标准......”这句话开头的,这听起来并不像听起来那么狡猾。使用的语言非常具体。考虑第一个条款
符合要求的实施应至少产生一种诊断 消息(以实现定义的方式标识)如果a 预处理翻译单元或翻译单元包含一个 违反任何语法规则或约束,即使行为是 也明确指定为未定义或实现定义。 在其他情况下不需要产生诊断信息.9
此子句明确指“违反任何语法规则或约束”。因此,格式良好的#error
指令不会触发此子句。因此它不适用,相互排斥是没有实际意义的。
另请注意最后一句,其中表示诊断“无需生成”。 “不必”并不意味着“必须”。它只是意味着实现可以选择是否为其他条件发出诊断(例如,样式问题)。但同样,整个条款与#error
您的第二个引言只是简单说明了一个实现必须对格式良好的#error
指令执行的操作。
答案 1 :(得分:4)
C99比该DR的建议分辨率更进了一步。他们不需要诊断,而是将其视为错误。
<强> 4。一致性强>
4实施不能成功翻译预处理翻译单元 包含
#error
预处理指令,除非它是跳过的组的一部分 条件包含。
现在,严格地说,也许你是对的,实现可以选择拒绝编译包含#error
指令的程序而不用发出诊断声称5.1.1.3允许它忽略#error
的语义。但是,在标准设置的范围内尽可能无用的实现很容易解决任何需要诊断的尝试:实现可以简单地转储完整的预处理器输出(包括{{1之后的任何内容)然后按照“某处出现错误”来表示。因此,标准是否需要诊断无关紧要。没有理由不执行此实施,并且标准可以强制执行不愿意的实施者。