C2x:6.9.2 外部对象定义:为啥“不应是不完整的类型”放在语义而不是约束中?

Posted

技术标签:

【中文标题】C2x:6.9.2 外部对象定义:为啥“不应是不完整的类型”放在语义而不是约束中?【英文标题】:C2x: 6.9.2 External object definitions: why is "shall not be an incomplete type" placed in Semantics rather than in Constraints?C2x:6.9.2 外部对象定义:为什么“不应是不完整的类型”放在语义而不是约束中? 【发布时间】:2021-12-08 11:10:49 【问题描述】:

后续问题:What is the rationale for "semantics violation does not require diagnostics"?。

N2596 工作草案 - 2020 年 12 月 11 日 ISO/IEC 9899:202x (E),6.9.2 外部对象定义,语义,3:

如果一个对象的标识符声明是一个暂定定义并且具有内部链接,则声明的类型不能是不完整的类型。

这看起来像是一个约束——为什么将它放在“语义”部分(违反要求不需要诊断)而不是放在“约束”部分?

UPD。类似问题:Understanding IEEE 754: why convertFromInt and convertToIntegerXXX are categorized as arithmetic operations and not conversion operations?.

【问题讨论】:

【参考方案1】:

这看起来像一个约束

我同意。

——为什么放在“语义”部分(违反要求不需要诊断)而不是“约束”部分?

关于括号,我不认为诊断是否需要成为语言约束和语义规则之间的关键区别的问题。一个约束是一个

限制,无论是句法还是语义,解释语言元素的阐述

(C17,3.8/1)

可以肯定的是,这有点拗口,但归根结底是约束,即哪些代码匹配 C 词法语法实际上总体上符合语言规范,哪些不符合。因此,始终可以在翻译时评估对语言约束的遵守情况,不能有效满足语言约束的代码不会用 C 表示。也就是说,约束是适用于源代码的规则。这是实现诊断违反约束的要求的上下文。

另一方面,语义规则解释了 C 代码的含义或相关的程序行为(如果有)。这些是程序运行时行为和 C 语言实现的规则。

这完全可以追溯到:我同意,尽管第 6.9.2/3 段被列在语义规则中,但本质上是一种语言限制。

我怀疑是否有人能够权威地回应为什么将其置于语义规则中,但在这里可能相关的是,完全相同的措辞在语言规范的每个已发布版本中都作为语义规则出现,所有回到 C89 的方式,它对“不完整类型”的定位与 C11 和更高版本略有不同。

可能是最初的 ANSI C 委员会在这里冒昧地原谅编译器诊断此问题,可能是因为他们认为该限制是否应适用于稍后在翻译单元中完成的不完整类型存在歧义。我自己也不确定,今天。这完全有可能代表了一种妥协的立场。

【讨论】:

仅供参考:similar question. 如果“约束”被定义为“限制,无论是句法还是语义......”,那么根据 5.1.1.3 诊断“......违反任何语法规则或约束......”也意味着“违反语义限制”,因此需要产生“至少一个诊断信息”。这与“semantics violation does not require diagnostics”相矛盾。您对此有何评论? @pmor,约束不是 every “限制,无论是句法还是语义”。它是一种“限制,无论是句法还是语义,通过它来解释语言元素的阐述”。在实践中,解释语言元素的解释是通过它们出现在标记为“约束”的部分中的事实来识别的。

以上是关于C2x:6.9.2 外部对象定义:为啥“不应是不完整的类型”放在语义而不是约束中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 printf 是在本地定义的,而 getchar 是在外部定义的?

为啥全局对象属性在函数后不更新?

关于 std::cout,为啥使用“外部”而不是“单例模式”

在条件(如果)内的要求(外部文件)中定义的 PHP7 const 正在工作 - 为啥?

外部、内部和没有联系或者为啥这不起作用?

为啥我的外部库方法无法解析?