实现定义的行为是未定义的行为吗

Is Implementation defined behaviour an undefined behaviour

我打开了一个C99标准。通道。 4 “一致性”,第 2 页内容如下:

如果违反出现在约束之外的“应该”或“不应”要求,则行为是未定义。 [...]

下面,第 1 页。 5 我们看到以下内容:

[...] (2) 它不应产生输出依赖于任何未指定、未定义、或 实现定义的行为 ,并且不得超过任何 最低实施限制。

这对我来说似乎表明实现定义的行为是未定义的行为,因为程序“不应”依赖于实现定义的行为。

现在,我有两个问题:

不,实现定义的行为不是未定义的行为。

第 5 段 严格 符合程序:

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

第 7 段及其脚注说明有 2 个级别的一致性:

  1. A conforming program is one that is acceptable to a conforming implementation. 4)

4) Strictly conforming programs are intended to be maximally portable among conforming implementations. Conforming programs may depend upon nonportable features of a conforming implementation.

具有实现定义行为的程序只是符合程序,但不是严格符合程序。

实现定义的行为与未定义的行为确实不同。

  • 实现定义的行为意味着实现必须选择一种可能的行为。例如,允许 char 有符号或无符号,没有其他可能的选择。
  • 未定义的行为意味着标准对可能的行为没有限制,从预期的行为到立即的程序崩溃。此外,优化编译器可以自由假设程序不包含 UB。这意味着如果您在条件 (if) 的分支中调用未定义行为,编译器可能会优化整个分支和测试。

This to me seems to suggest that implementation-defined behaviour is undefined behaviour /--/ Is implementation behaviour undefined after all? Yes/no, why?

不,因为那里没有定义术语。它们甚至是在第 3 章中找到的正式术语,术语:

3.4.3
undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

3.4.4 unspecified behavior
use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance

3.4.1 implementation-defined behavior
unspecified behavior where each implementation documents how the choice is made


because a program "shall not" depend on implementation-defined behaviour.

您正在阅读严格符合程序的定义。也就是说,一个程序不包含任何扩展,也没有定义不明确的行为。该术语在 符合实现 的定义中主要有意义,意思是符合标准的编译器。如果编译器接受任何严格符合的程序,那么它就是符合标准的。


What does "outside of constraint", mentioned in Ch.4 p. 2 mean?

该标准有一些额外的重要部分称为约束 - 也是一个正式术语,您可以在第 3 章中找到:

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

如果程序违反任何约束或语法规则,编译器需要忽略诊断消息。例如,如果我们阅读加法运算符 6.5.6 的定义,它是:

Constraints
For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type.

因此,如果我用两个结构编写代码 mystruct1 + mystruct2,那就是 约束违规 ,因为我的操作数既不是算术类型也不是指针类型。 (这也是未定义的行为,因为它违反了标准的 'shall' 要求。)

C 标准以不同于大多数标准的方式使用术语“应”。明确的意图是违反约束的程序不能是严格符合的程序,但是如果不严格符合的程序违反了约束,这意味着标准放弃了对实现如何处理程序的管辖权,所以以允许他们以最能为客户服务的任何方式处理它。该标准并未试图禁止实现以对客户不利的方式处理此类构造,因为他们认为编译器编写者会设法使他们的编译器对程序员具有最大的吸引力。

我想人们可以用与在其他地方使用的方式相同的方式来解释严格符合程序定义中的“应”,这意味着即使在该定义内违反约束也只是放弃管辖权,但是这将使术语“严格一致的 C 程序”与术语“一致的 C 程序”一样毫无意义,甚至比术语“一致的 C 实现 (*)”更无意义,后者看起来相当愚蠢。

(*) “一个程序规则”指定符合标准的 C 实现必须以标准定义的方式正确处理至少一个可能人为设计且无用的程序,该程序执行 N1570 5.2.4.1 中给出的翻译限制,但任何其他源文本的实现都不会使其不符合要求。已发布的基本原理明确表示,将实现处理有用程序的能力视为“实现质量”问题,而不是一致性问题。