简体   繁体   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

Word limit on question length..问题长度的字数限制..

As pointed out by @Karl Knechtel I am confused that isn't fetching the operation of the array indexing unsequenced relative to the i++ increment operation?正如@Karl Knechtel所指出的,我很困惑,没有获取相对于i++增量操作未排序的数组索引操作? If they are unsequenced, why the C Standard 6.5.2 line mentioning about (emphasis added to the words/phrase which i understand, applies here)如果它们未排序,为什么 C 标准 6.5.2 行提到关于(强调添加到我理解的单词/短语,适用于此处)

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object , the behavior is undefined.如果标量 object 上的副作用对于同一标量 object 上的不同副作用或使用相同标量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z的值的值计算未排序,则行为未定义。

I read this question I can not understand some sentences in C99 wherein the OP tries to understand why a[i++] = 1 is undefined.我读了这个问题,我无法理解 C99 中的一些句子,其中 OP 试图理解为什么a[i++] = 1未定义。 Accepted and one of the highest voted answers by Pascal Cuoq mentions that this is defined behavior. Pascal Cuoq接受且投票率最高的答案之一提到这是已定义的行为。

I also tried compiling the program using the -std=c99 , -Wall and -Wextra flag and a slew of other flags (basically all the flags which are enabled in GCC 11.2.0), but the code didn't throw any warning .我还尝试使用-std=c99-Wall-Wextra标志以及大量其他标志(基本上是在 GCC 11.2.0 中启用的所有标志)编译程序,但代码没有抛出任何警告

However, my question/confusion is why is this a defined behaviour?但是,我的问题/困惑是为什么这是一个明确的行为?

From the C11 standard S6.5.2C11 标准S6.5.2

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.如果标量 object 上的副作用相对于同一标量 object 上的不同副作用或使用相同标量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值计算未排序,则行为未定义If there are multiple allowable orderings of the subexpressions of an expression, the behaviour is undefined if such an unsequenced side effect occurs in any of the orderings.如果表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为未定义。

my understanding/reasoning after reading through most of the threads on SO (with Tags [C] and [sequence-points] ) is that i++ would result in a side effect of updating the value of i.在阅读了 SO 上的大多数线程(带有标签[C][sequence-points] )后,我的理解/推理是 i++ 会导致更新 i 的值的副作用。 in that case this side-effect is unsequenced to the value computation using the same scaler object.在这种情况下,这种副作用与使用相同的缩放器 object 的值计算无关。 I understand that a[integer object] constitutes value computation .我知道a[integer object]构成了value computation Then, it should be undefined behavior?那么,它应该是未定义的行为吗?

Even from the C99 S6.5(p2)甚至从 C99 S6.5(p2)

Furthermore, the prior value shall be read only to determine the value to be stored.此外,应仅读取先验值以确定要存储的值。

I understand/construe that this expression should also render a[i++] = 1 undefined?我理解/理解这个表达式也应该使a[i++] = 1未定义?

in that case this side-effect is unsequenced to the value computation using the same scaler object.在这种情况下,这种副作用与使用相同的缩放器 object 的值计算无关。

The scalar object involved in i++ is i . i++中涉及的标量 object 是i The side effect of updating i is not unsequenced relative to the computation of the value of i++ because C 2018 6.5.2.4 (which specifies behavior of postfix increment and decrement operators) paragraph 2 says:相对于i++的值的计算而言,更新i的副作用并非无序,因为 C 2018 6.5.2.4(指定后缀递增和递减运算符的行为)第 2 段说:

… The value computation of the result is sequenced before the side effect of updating the stored value of the operand… ......结果的值计算在更新操作数的存储值的副作用之前排序......

C 2011 has the same wording. C 2011 具有相同的措辞。 (C 2018 contains only technical corrections and clarifications to C 2011.) (C 2018 仅包含对 C 2011 的技术更正和说明。)

Even from the C99 S6.5(p2)甚至从 C99 S6.5(p2)

Furthermore, the prior value shall be read only to determine the value to be stored.此外,应仅读取先验值以确定要存储的值。

A rule in the C 1999 standards has no application to the 2011 or 2018 standards; C 1999 标准中的一条规则不适用于 2011 或 2018 标准; it must be interpreted separately.它必须单独解释。 Between 1999 and 2011, the standard moved from solitary sequence points to finer rules about sequencing relationships.在 1999 年到 2011 年间,该标准从单独的序列点转变为关于序列关系的更精细的规则。

In i++ , the prior value is read to determine what the new value of i should be, so it conforms to that rule.i++中,读取先前的值以确定i的新值应该是什么,因此它符合该规则。

The rule was an attempt to say that any reads of a scalar object had to be in the prerequisite chain of an writes of the object.该规则试图说明标量 object 的任何读取都必须位于 object 写入的先决条件链中。 For example, in i = 3*i + i*i , all three reads of i are necessary to compute the value to be written to i , so they are necessarily performed before the write.例如,在i = 3*i + i*i中,所有三个i的读取都是计算要写入i的值所必需的,因此它们必须在写入之前执行。 But in i = ++i + i;但在i = ++i + i; , the read of i for that last term is not a prerequisite for writing to i for the ++i , so it is not necessarily performed before the write. , 最后一项的i的读取不是++i写入i的先决条件,因此不一定在写入之前执行。 Thus, it would not conform to the rule.因此,它不符合规则。

… I am confused that isn't fetching the operation of the array indexing unsequenced relative to the i++ increment operation? …我很困惑,没有获取相对于i++增量操作未排序的数组索引操作?

The read of the array element is unsequenced relative to the update of i , and that is okay because there is no rule that requires it to be sequenced.数组元素的读取相对于i的更新是无序的,这没关系,因为没有规则要求它被排序。 C 2018 6.5 2 says, emphasis added: C 2018 6.5 2 说,强调补充:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.如果标量 object 上的副作用相对于同一标量 object 上的不同副作用或使用相同量 ZA8CFDE6331BD59EB2AC96F8911C4B66Z 的值的值计算未排序,则行为未定义

The array element is a different scalar object from i , so we do not care that there is no sequencing between the read of the array element and the update to i .数组元素是与i不同的标量 object ,因此我们不关心数组元素的读取和对i的更新之间没有排序。

Thanks a lot for the immediate responses from members.非常感谢会员的即时回复。 I would try to attempt an answer in the language, which, I understood.我会尝试用我理解的语言来回答。

After reading a suggestion to read this article use of abstract tree to tackle sequence point problem (I know, it's not normative)在阅读了阅读这篇文章的建议后,使用抽象树解决序列点问题(我知道,这不是规范的)

Let me represent a[i++] =1 using the abstract syntax tree.让我使用抽象语法树来表示 a[i++] =1。

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

在此处输入图像描述

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

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