0

I'm writing a stack implementation in C. The stack structure contains an int 'top', which contains the index of the value at the top of the stack. Therefore, to push something to the stack, it makes sense to use something like stack[++top] = new_value. I see this pattern of incrementing a variable in an array subscript all the time, and it saves a line of code.

However, this C style guide has this to say about the above code:

Do not use expressions with side-effects in complicated ways. Do not assume that
the compiler evaluates things between sequence points in a particular order.

    a[i++] = i; /* undefined behaviour! */

Is this really true? And, if it is, why? Since a lot of code uses this pattern, I would assume most modern compilers support it, which means it should've been adopted into a standard at some point. After all, if you really shouldn't use it, what's the point of differentiating between ++i and i++?

  • 5
    `stack[++top] = new_value` is valid because `top` and `new_value` are different variables. But `a[i++] = i;` is UB because it uses same variable `i` in both part. – Afshin Jan 30 '22 at 13:58
  • 1
    @Afshin So the only reason `a[i++] = i` is undefined is because its unclear what the value of `i` will be when it gets added to the array. Thank you –  Jan 30 '22 at 14:02
  • `a[i++] = i;` leads to undefined behavior because `i` appears on both sides of the assignment. –  Jan 30 '22 at 14:04
  • 1
    @spitemim The problem is not the assignment, but that `i` is evaluated to the value it holds on the right-hand side, while the modification on the left-hand side is not sequenced before or after this evaluation. – user17732522 Jan 30 '22 at 14:04
  • @spitemim if you oversimplify things yes. but check here for details: https://en.cppreference.com/w/cpp/language/eval_order it says: *" If a side effect on a scalar object is unsequenced relative to a value computation using the value of the same scalar object, the behavior is undefined. "* Which to be fair, I still don't get exactly myself. – Afshin Jan 30 '22 at 14:05
  • 1
    @spitemim Think of the `i++` and fetch of `i` in `= i;` happening 1) in one order, 2) the opposite order, 3) at the same time, or 4) even a bus-conflict as the `i++` attempts to write `i` while the `i` in `= i;` is being read. 1 & 2 lead to different results, 3 is a coin-flip and 4 can kill the program. C does not define what happens in this case. It is _undefined behavior_. – chux - Reinstate Monica Jan 30 '22 at 14:31

0 Answers0