C2x:6.9.2 外部对象定义:为什么 "shall not be an incomplete type" 放在语义而不是约束中?

C2x: 6.9.2 External object definitions: why is "shall not be an incomplete type" placed in Semantics rather than in Constraints?

后续问题:

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

If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type.

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

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

This looks like a constraint

同意。

— why is it placed in the section "Semantics" (a violation of the requirement does not require a diagnostic) rather than in the section "Constraints"?

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

restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted

(C17, 3.8/1)

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

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

这是一个很长的路要走:我同意,尽管被列在语义规则中,第 6.9.2/3 段本质上是一个语言限制。

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

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