繁体   English   中英

不是 a[i++] = 1 (one) 其中,增量的计算相对于数组的索引是无序的,导致违反 S6.5.2

[英]Isn't a[i++] = 1 (one) where, computation of the increment to be unsequenced relative to the indexing of the array, leading to violation of S6.5.2

问题长度的字数限制..

正如@Karl Knechtel所指出的,我很困惑,没有获取相对于i++增量操作未排序的数组索引操作? 如果它们未排序,为什么 C 标准 6.5.2 行提到关于(强调添加到我理解的单词/短语,适用于此处)

如果标量 object 上的副作用对于同一标量 object 上的不同副作用或使用相同标量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z的值的值计算未排序,则行为未定义。

我读了这个问题,我无法理解 C99 中的一些句子,其中 OP 试图理解为什么a[i++] = 1未定义。 Pascal Cuoq接受且投票率最高的答案之一提到这是已定义的行为。

我还尝试使用-std=c99-Wall-Wextra标志以及大量其他标志(基本上是在 GCC 11.2.0 中启用的所有标志)编译程序,但代码没有抛出任何警告

但是,我的问题/困惑是为什么这是一个明确的行为?

C11 标准S6.5.2

如果标量 object 上的副作用相对于同一标量 object 上的不同副作用或使用相同标量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值计算未排序,则行为未定义如果表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为未定义。

在阅读了 SO 上的大多数线程(带有标签[C][sequence-points] )后,我的理解/推理是 i++ 会导致更新 i 的值的副作用。 在这种情况下,这种副作用与使用相同的缩放器 object 的值计算无关。 我知道a[integer object]构成了value computation 那么,它应该是未定义的行为吗?

甚至从 C99 S6.5(p2)

此外,应仅读取先验值以确定要存储的值。

我理解/理解这个表达式也应该使a[i++] = 1未定义?

在这种情况下,这种副作用与使用相同的缩放器 object 的值计算无关。

i++中涉及的标量 object 是i 相对于i++的值的计算而言,更新i的副作用并非无序,因为 C 2018 6.5.2.4(指定后缀递增和递减运算符的行为)第 2 段说:

......结果的值计算在更新操作数的存储值的副作用之前排序......

C 2011 具有相同的措辞。 (C 2018 仅包含对 C 2011 的技术更正和说明。)

甚至从 C99 S6.5(p2)

此外,应仅读取先验值以确定要存储的值。

C 1999 标准中的一条规则不适用于 2011 或 2018 标准; 它必须单独解释。 在 1999 年到 2011 年间,该标准从单独的序列点转变为关于序列关系的更精细的规则。

i++中,读取先前的值以确定i的新值应该是什么,因此它符合该规则。

该规则试图说明标量 object 的任何读取都必须位于 object 写入的先决条件链中。 例如,在i = 3*i + i*i中,所有三个i的读取都是计算要写入i的值所必需的,因此它们必须在写入之前执行。 但在i = ++i + i; , 最后一项的i的读取不是++i写入i的先决条件,因此不一定在写入之前执行。 因此,它不符合规则。

…我很困惑,没有获取相对于i++增量操作未排序的数组索引操作?

数组元素的读取相对于i的更新是无序的,这没关系,因为没有规则要求它被排序。 C 2018 6.5 2 说,强调补充:

如果标量 object 上的副作用相对于同一标量 object 上的不同副作用或使用相同量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值计算未排序,则行为未定义

数组元素是与i不同的标量 object ,因此我们不关心数组元素的读取和对i的更新之间没有排序。

非常感谢会员的即时回复。 我会尝试用我理解的语言来回答。

在阅读了阅读这篇文章的建议后,使用抽象树解决序列点问题(我知道,这不是规范的)

让我使用抽象语法树来表示 a[i++] =1。

表达式 a[i++] = 1 的抽象树表示;

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM