【问题标题】:Can extension cancel the existing standard requirements?延期可以取消现有的标准要求吗?
【发布时间】:2021-10-11 10:39:44
【问题描述】:

Why do conforming implementations behave differently w.r.t. incomplete array types with internal linkage? 的后续问题。

上下文:在 gcc 和 clang(一致的实现)中,默认情况下,要求 C11,6.9.2p3 [1] 被取消,它被定位为扩展。

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

[1] C11,6.9.2 外部对象定义,3:

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

UPD。是的。换句话说:标准说:“我们不支持这个,需要诊断”。扩展程序说:“我们确实支持这一点(因此,标准所需的诊断是无关紧要的)”。

【问题讨论】:

  • AFAIK gcc 不声称符合要求,除非使用-pedantic
  • 标准的规则不就是如果源代码违反约束,编译器必须发出诊断,然后可以继续做它喜欢的任何事情(例如忽略违规)吗?在您的另一篇文章中,gcc -pedantic 确实发出了诊断信息,所以它已经摆脱了困境。 gcc 本身不会发出诊断,因此它不符合要求,但它又从未声称是。
  • @NateEldredge 关于gcc -pedantic:有这样的引用:“报告任何不符合 ISO C 的功能在某些情况下可能很有用,但需要大量额外的工作并且会完全不同来自 -Wpedantic。我们没有计划在不久的将来支持这样的功能。”。
  • 对。一些不符合标准的程序会执行标准需要诊断的操作,而其他程序则不需要。 gcc -pedantic 应该为第一类发出诊断。他们提到的这个假设特征将解决第二种程序。
  • @NateEldredge 仅供参考:观察 gcc:-pedantic 的存在/不存在不会改变 __STDC__ 的定义(即 1)。 clang 也是一样。

标签: c language-lawyer c11 standards-compliance c17


【解决方案1】:

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

一致的实现的定义如下来自C11 standard的第4p6节:

两种形式的一致的实现被托管和 独立式。 符合要求的托管实施应接受 任何严格遵守的程序。 一致的独立实现应接受任何严格一致的程序,其中库条款(第 7 条)中指定的功能的使用仅限于标准头文件的内容 [ ... 省略为简洁起见 ...]。 符合的 实现可能有扩展(包括额外的库 功能),只要它们不改变任何行为 严格符合程序

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

一个严格符合的程序应该只使用那些特性 本国际规定的语言和图书馆的 标准。它不应产生依赖于任何 未指定、未定义或实现定义的行为,以及 不得超过任何最低实施限制

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

符合标准的程序是符合标准的实现可接受的程序。

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

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 };

从行为上有所不同。因此,支持此功能的实现仍然有资格作为符合标准的实现。这也意味着第一个程序虽然不是一个严格符合的程序,但它是一个符合程序,因为它将在符合要求的实现上以明确定义的方式运行。

【讨论】:

  • 谢谢。换句话说:标准说:“我们不支持这一点,需要诊断”。扩展名说:“我们确实支持这一点(因此,标准所需的诊断是无关紧要的)”。其他相关问题:这是否意味着“将sizeof 应用于不完整类型而没有任何诊断”也可以定位为扩展?
  • @pmor 是的,事实上 gcc 对void 有这个扩展:gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
【解决方案2】:

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

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

【讨论】:

  • 回复:如果程序超出实现的翻译限制,则该实现可能会以任何方式运行:这里是relevant question
  • Re:极少数情况:出于好奇,这些极少数情况是什么?
  • @pmor:如果一个实现被设计成恰好有一个可能的源文本行使了标准规定的翻译限制,那么这样的实现,如果它符合文档和诊断消息要求,将符合要求。但是,如果它未能按照标准的规定处理该程序,那么“其他符合”的实现将不再符合。
猜你喜欢
  • 2012-07-16
  • 2011-03-28
  • 1970-01-01
  • 2015-09-21
  • 2016-04-11
  • 2017-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多