Introduction
The C11 standard (ISO/IEC 9899:2011) has introduced a new definition of side effect sequencing within an expression (see related question). The sequence point concept has been complemented with sequenced before and sequenced after relations which are now the basis for all definitions.
Section 6.5 "Expressions", point 2 says:
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 behavior is undefined if such an unsequenced side effect occurs in any of the orderings.
Later on, section 6.5.16 "Assignment operators", point 3 states:
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.
Problem
The first quoted paragraph (6.5/2) is supported by two examples (same as in the C99 standard):
First example
a[i++] = i; //! undefined
a[i] = i; // allowed
This can be easily explained with the definitions:
- 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. (6.5/2),
- The evaluations of the operands are unsequenced. [within an assignment] (6.5.16/3).
So, the side effect of i++
(LHS) is unsequenced with i
(RHS), which gives undefined behaviour.
Second example
i = ++i + 1; //! undefined
i = i + 1; // allowed
This code, however, seems to result in a defined behaviour in both given cases as:
- the side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands.
So, the execution of ++i + 1
shall precede the side effect of updating i
, which means that there is not a side effect on a scalar object 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.
Question
It is easy to explain these examples with the terms and definitions presented by the C99 standard (see related question). But why is i = ++i + 1
undefined according to C11's terminology?
++i
has different meaning in C and C++. – Roborant