i=i++ 会在 C17 中重新定义吗?

Will i=i++ be newly well-defined in C17?

在今天偶然发现问题“Why are these constructs using pre and post-increment undefined behavior?”后,我决定获取下一个 C 标准的最新草案,我可以找到并阅读更多相关信息。
在我发现 C17 草稿中的以下段落后不久:

An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof. The value computations of the operands of an operator are sequenced before the value computation of the result of the operator
Source: ISO/IEC 9899:2017, Section 6.5 §1 "Expressions" (link broken use web.archive.org)

现在我有点困惑。这是否意味着 i = i++ 是已定义的行为?这次我看了另一个草稿,C99:

An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.
Source: ISO/IEC 9899:1999, Section 6.5 §1 "Expressions"

就是漏了那句话!

问题

  1. 我是不是误会了什么?
  2. 答案是否过时?
  3. 我是不是看错草稿了?

注意:是相关的,不过是关于C++的。

您突出显示的段落仅说明表达式 i++i 在对完整表达式 i = i++ 求值之前求值。它仍然是未定义的行为,因为 i 在没有序列点的表达式中被修改了不止一次。

该段首次出现在 C11,因此与 C17 版本没有任何变化。

全文。在 C99 中,我们有 6.5.16 赋值运算符的文本:

The side effect of updating the stored value of the left operand shall occur between the previous and the next sequence point.

The order of evaluation of the operands is unspecified. If an attempt is made to modify the result of an assignment operator or to access it after the next sequence point, the behavior is undefined.

这在 C11 中更改为:

The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

这只是不同(而且更糟)的措辞,两个版本的行为相同 - 关键是 C11 部分中的最后一句话仍然导致这种未定义的行为,因为左操作数的计算在关系中仍然是未排序的到正确的操作数。值计算仅指单个操作数。

C17 与 C11 具有相同的文本。所以答案是:不,i = i++; 在 C17 中仍然是未定义的行为。


仅供参考,将其与 C++11 (5.17) 进行比较:

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

这与 C11 大致相同,没有显式 "the evaluations of the operands are unsequenced"。这是 C++11 中的一个缺陷,尚不清楚这是否会使某些表达式定义明确。

C++17 提供了澄清(8.5.18):

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand.

所以在C++17中,i=i++;绝对是定义明确的。正如我们所看到的,措辞是明确的,而不是 C11/C17.

中的 "unsequenced"