C 和 C++ 标准如何告诉您如何处理它们未涵盖的情况?

che*_*nov 5 c c++ standards iso language-lawyer

众所周知,在每个 C 和 C++ 标准中都存在“盲点”,这些“盲点”没有描述格式良好的程序中的某些情况。显然,在这种复杂的形式系统的非形式化描述中,不可能提前注意到一切。

\n

因此,在发布新的修订版(“版本”)之前,有一个纠正和解释标准的既定程序。让我们使用最简单且按时间顺序排列的第一个示例来考虑这一点 - C90 标准 ( ISO/IEC 9899:1990 ),该标准现已正式撤回。

\n

为此发布了以下类型的文件(按照重要性递减的顺序):

\n
    \n
  1. ISO 技术勘误表 (TC)

    \n

    事实上,这些是一种直接应用于现有标准并具有追溯效力的“补丁”。实际上,这意味着,如果新文档以其他方式澄清了这些地方,那么所有以前以自己的方式解释标准模糊部分的合规实现都将变得不合规。

    \n

    对于 C90,发布了两个这样的文档:TC-1:1994TC-2:1996

    \n
  2. \n
  3. ISO 修正案 (Amd),又名ISO 规范附录 (NA)

    \n

    与 TC 的效果非常相似,并且实际上具有相同的影响,但可能通过某种机制限制其追溯效果 - 例如通过引入新的值__STDC_VERSION__

    \n

    通常,ISO 修正案意义重大且规模庞大,因此很少发布。但无论如何,C90 已经发布了 - Amd-1:1995

    \n
  4. \n
  5. WG14 缺陷报告 (DR),又名Clari\xef\xac\x81cation 请求

    \n

    这些是致标准化委员会的信函,要求澄清标准中某些有争议的段落,并提请注意标准中的各种缺陷。委员会对这些问题进行讨论,公开表达其集体意见,这些意见最终可能会出现在正式批准的文件中(TC、NA 甚至标准本身)。

    \n

    然而,缺陷报告本身并不是正式文件,因此不具有强制性追溯效力。尽管如此,实施者和普通开发人员可以依靠它们来避免未来不合格的命运,或者至少减少其发生的可能性。

    \n

    对于 C90 标准,包括所有上述补充内容,已处理了 178 份报告,其列表可在委员会的官方网站上找到:
    \n https://www.open-std.org/jtc1/sc22/ wg14/www/docs/dr.htm
    \n https://www.open-std.org/jtc1/sc22/wg14/www/docs/c90_drs.html

    \n
  6. \n
\n
\n

由于标准既不为编译器也不为标准库提供参考(模型)实现,因此需要不断澄清和编辑。并非所有实施者都可能有兴趣完全支持新标准,也并非所有开发人员都希望重写他们维护的旧代码 - 这是生活和商业的事实。但同样明确的是,TC和DR不能无限地为旧标准颁发。

\n

因此,出现了以下问题:

\n
    \n
  1. 如何处理未明确声明为实现定义未指定甚至未定义的未指定行为未指定行为?

    \n
  2. \n
  3. 在这种情况下是否应该参考新的标准?

    \n
  4. \n
  5. 是否应该针对撤回的标准提交缺陷报告?

    \n
  6. \n
\n

请注意,我不仅谈论编译器和标准库程序员,还谈论常规代码编写者。

\n
\n

也可以看看:

\n\n

Joh*_*ger 7

C 和 C++ 标准如何告诉您如何处理它们未涵盖的情况?

语言规范解释了各自语言的一致实现的行为方式。他们没有提到应该如何表现。


  1. 如何处理未明确声明为实现定义、未指定甚至未定义的未指定行为?

规范不必明确说明行为未定义。C 特别这样定义“未定义的行为”:

使用不可移植或错误的程序构造或错误数据时的行为,本国际标准对此没有强加要求

(C17 3.4.3/1)。

C 语言规范的所有版本都有这种或非常相似的措辞,我很确定 C++ 也是如此。

至于如何治疗,避免它是最安全的。或者,对于“未指定”或“实现定义”的行为,如果规范允许的所有替代方案都可以接受,您可以安全地忽略它。

或者,如果您专门针对定义相关行为的实现(无论适用的规范是否使其成为“实现定义”),并且您不关心其他实现的可移植性,那么您可以依赖您的实现的文档。


  1. 在这种情况下是否应该使用更新的标准?

依赖不适用于您实际使用的实现的文档是没有意义的。假设仅由较新版本的规范定义的行为将通过(仅)较早版本的规范的实现来体现是不安全或不合理的。

但是,您可以考虑切换到更新规范的实现。另请参阅上文。


  1. 是否应该针对撤回的标准提交缺陷报告?

这似乎不太可能有用。您应该理解标准(的一个版本)的撤回意味着该标准将不再得到进一步维护。

对于 C 和 C++ 语言规范,如果您的问题在最新版本的规范中得到解决,那么委员会肯定会认为已经充分解决了该问题。如果没有,那么您可以考虑针对当前版本提交灾难恢复,并理解任何修复都将针对该规范或未来版本的规范。