1

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? 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)

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.

I read this question I can not understand some sentences in C99 wherein the OP tries to understand why a[i++] = 1 is undefined. Accepted and one of the highest voted answers by Pascal Cuoq mentions that this is defined behavior.

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.

However, my question/confusion is why is this a defined behaviour?

From the C11 standard 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. 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. in that case this side-effect is unsequenced to the value computation using the same scaler object. I understand that a[integer object] constitutes value computation. Then, it should be undefined behavior?

Even from the 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?

Singh
  • 55
  • 1
  • 6
  • 3
    If you really read the C standard, you should find that for postfix ++, ["The value computation of the result is sequenced before the side effect of updating the stored value of the operand."](http://port70.net/~nsz/c/c11/n1570.html#6.5.2.4p2) I don't understand why you think that the side effect is unsequenced to the value computation. – cpplearner Jan 20 '22 at 14:51
  • Re “my understanding/reasoning after reading through most of the threads on SO”: To know what the C standard says, read the C standard first. – Eric Postpischil Jan 20 '22 at 14:53
  • "in that case this side-effect is unsequenced to the value computation using the same scaler object." No, that doesn't follow. Some computations using the same object can be sequenced. "I understand that a[integer object] constitutes value computation" And that computation is sequenced relative to the increment - it's not possible to index into `a` until *after* the index has been calculated. The reason `a[i++] = i` is undefined is because the right-hand side still has to be evaluated, even if it's just a variable by itself, and that evaluation isn't sequenced relative to `i++`. – Karl Knechtel Jan 20 '22 at 14:53
  • 2
    @cpplearner I think OP expects the computation of the increment to be unsequenced relative to *the indexing of the array*. – Karl Knechtel Jan 20 '22 at 14:56
  • If the side-effect of storing the incremented value was un-sequenced with reading the prior value then `i++` is undefined let alone `a[i++]=1`. But those sentences @cpplearner mention the relative sequence relating to that scalar value (i) is defined. What isn't defined is relative to other calculations like determining the l-value a[i] and storing 1 in it. But it talks about side-effects on a scalar object itself. Not other side-effects on other scalar objects. – Persixty Jan 20 '22 at 15:11
  • I wonder if everyone is confusing the 1 (one) with the i (letter I). – Braiam Jan 20 '22 at 15:34
  • @Braiam, I intend it to be 1 (one) – Singh Jan 20 '22 at 15:35
  • 2
    Singh, For clarity, 1) it would have been better to use variable names and constants that do not look like each other - too late now. 2) Synchronize the title with the internal question "why is this a defined behaviour?" – chux - Reinstate Monica Jan 20 '22 at 15:42
  • Where do you see anything unsequenced in the code example? – Braiam Jan 20 '22 at 16:04
  • @Braiam let me try to breakdown, the expression, a[i++] = 1; into sub-steps.. `temp1=i; temp2=temp1+1; i=temp2;` my confusion is why `a[temp1]` is defined? Doesn't S6.5.2, means that **If a side effect on a scalar object is unsequenced relative to** either .. or **a value computation using the value of the same scalar object**, the behavior is undefined. Wouldn't value computation `a[temp1]` using same scaler object `i (english alphabet)`, thus leading to unsequencing of side-effect (i = temp2;)? thus, leading to undefined behavior? – Singh Jan 20 '22 at 16:48
  • Why should the compiler care what a[temp1] is? It needs the index value and that has to be calculated before hand. It will simply wait. – Braiam Jan 20 '22 at 17:23
  • @Singh Notice it talks about side-effect *on* a scalar object. `a[i]` *uses* the value of `i` but it isn't a side-effect on `i`. So it's correct that the side-effect of storing of 1 in `a[temp1]` where temp1 is the prior value of i is un-sequenced with the storing of i++ it's not a side-effect *on* i itself. C doesn't prescribe a total order of evaluation and side-effects. Whether a[temp1] is stored before or after, in parallel or interleaved with storing temp1+1 to i is undefined by C and may be any or all of those in different executions. – Persixty Jan 20 '22 at 18:11

2 Answers2

5

in that case this side-effect is unsequenced to the value computation using the same scaler object.

The scalar object involved in i++ is 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:

… 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 2018 contains only technical corrections and clarifications to C 2011.)

Even from the 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; it must be interpreted separately. Between 1999 and 2011, the standard moved from solitary sequence points to finer rules about sequencing relationships.

In i++, the prior value is read to determine what the new value of i should be, so it conforms to that rule.

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. 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. But in 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. 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?

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. C 2018 6.5 2 says, emphasis added:

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.

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.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Could you please reply on what Karl Knechtel mentioned in his comment? I am sorry for unintentionally misrepresenting my question. Comment by @Karl is what is my core confusion? – Singh Jan 20 '22 at 15:13
  • I don't see in your answer mentioning the 1, but just focusing in the i. The code is element of array equals 1. – Braiam Jan 20 '22 at 15:35
  • @Braiam: The `1` is not a scalar object and has no bearing on the question. – Eric Postpischil Jan 20 '22 at 15:45
  • Except it does: "wherein the OP tries to understand why `a[i++] = 1` is undefined. Accepted and one of the highest voted answers by Pascal Cuoq mentions that this is defined behavior." That's correct. `a[i++] = 1` is defined. `= i` is undefined, but the question doesn't mention it. Otherwise, maybe we should replace i and 1 for j to force everything to be coherent. – Braiam Jan 20 '22 at 15:53
  • @Braiam: OP’s question about whether `a[i++] = 1` is defined or undefined has nothing to do with the `1`. It is expressed here: “… i++ would result in a side effect of updating the value of i. in that case this side-effect is unsequenced to the value computation using the same scaler object…” Thus we see the question is about the value computation of `i++` and the side effect of `i++`. The `1` is not involved. Their question may have come from something where `= 1` versus `= i` was at issue, but it is not at issue in this derivative question. – Eric Postpischil Jan 20 '22 at 15:59
-1

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.

Abstract tree representation of the expression a[i++] = 1;

enter image description here

Singh
  • 55
  • 1
  • 6
  • Your image of text [isn't very helpful](//unix.meta.stackexchange.com/q/4086). It can't be read aloud or copied into an editor, and it doesn't index very well, meaning that other users with the same problem are less likely to find the answer here. Please [edit] your post to incorporate the relevant text directly (preferably using copy+paste to avoid transcription errors). – Toby Speight Jan 27 '23 at 11:00