扩展是否可以取消现有的标准要求?

Can extension cancel the existing standard requirements?

的后续问题。

上下文:在gcc和clang(符合实现)中默认取消要求C11,6.9.2p3 [1],定位为扩展。

问题:扩展是否可以取消现有标准要求,同时保持实施符合要求?

[1] C11,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.

更新。是的。换句话说:标准说:“我们不支持这个,诊断是必需的”。扩展说:“我们确实支持这个(因此,标准要求的诊断是无关紧要的)”。

标准要求,如果程序违反约束部分中的约束,则实现必须至少发出一个诊断。没有关于文档是否有意义或与约束违反有任何关系的要求。无条件输出“警告:此实现不尝试强制执行其作者认为愚蠢的约束”的实现就足够了。同样,一个包含命令行选项的实现可以输出这样的消息和文档,除非指定该选项,否则它可能不符合要求。

请注意,即使该要求也存在漏洞:如果程序超出了实现的转换限制,则该实现可以不受限制地以任何方式运行,并且无需发出任何类型的诊断。尽管标准要求每个实现都必须至少存在一个源程序,该源程序至少在名义上执行标准中给出的转换限制而不会导致实现出现故障,但实现可能会对转换限制的交互方式施加任意限制,例如允许程序包含一个最多 63 个字符的标识符,或包含不超过三个字符的更多标识符。在极少数情况下,符合规范的实现可能对特定源文本所做的任何事情都会使其不符合规范。

与其说实现“取消”了扩展的要求,不如说扩展添加了标准不支持的功能。主要要求是扩展不会改变任何严格遵守的程序

符合规范的实现 的定义如下 C11 standard 的第 4p6 节:

The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers [ ... omitted for brevity ... ]. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program

其中 严格符合程序 在第 4p5 节中定义:

A strictly conforming program shall use only those features of the language and library specified in this International Standard. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit

并且在第 4p7 节中定义了一个符合程序

A conforming program is one that is acceptable to a conforming implementation.

鉴于您之前问题中的程序案例:

static int arr[ ];

int main( void )
{
        return arr[ 0 ];
}

static int arr[ ] = { 0 };

这不是严格遵守的程序,因为它违反了 6.9.2p3。然而,一些实现如 gcc 允许将其作为扩展。支持这样的功能不会阻止类似的严格符合程序,例如这个

static int arr[1];

int main( void )
{
        return arr[ 0 ];
}

static int arr[ ] = { 0 };

从行为上有任何不同。因此,支持此功能的实现仍然有资格作为 符合规范的实现 。这也意味着第一个程序虽然不是严格符合的程序,但却是 符合的程序 因为它将 运行 在符合的实现上以明确定义的方式 [=16] =]