I have read about undefined behaviour.
This Link says a[i] = a[i++]
leads to undefined behaviour.
But I don't understand why the output of
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int i = 0;
cout << arr[++i] + ++i << " " << i;
is 3 2
and the output of
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int i = 0;
cout << ++i + arr[++i] << " " << i;
is 4 2
Firstly - a[i] = a[i++]
is well-defined since C++17. The sequencing rules were considerably tightened in that revision of the Standard, and the evalution of the right-hand side of an assignment operator is sequenced before the evaluation of the left hand side, meaning that all side-effects of the right-hand side must be complete before evaluation of the left-hand side begins.
So that code is equivalent to a[i+1] = a[i]; ++i;
Since C++17, the <<
operator also has left-right sequencing, i.e. the left operand is sequenced before the right operand.
Now, ++i
is defined as i+=1
and similar considerations as above apply to the evaluation of the compound assignment operator. The ++i
occurs "atomically" we could say.
However, the +
operator is still unsequenced, this is defined by [intro.execution]/17:
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
[...]
If a side effect on a memory location is unsequenced relative to either another side effect on the same memory location or a value computation using the value of any object in the same memory location, and they are not potentially concurrent, the behavior is undefined
Unfortunately this means the behaviour of ++i + a[++i]
is still undefined, because the left operand of +
modifies i
, and the right operand of +
modifies i
, and those operand evaluations are unsequenced relative to each other.
It has previously been proposed to make +
and similar operators be left-right sequenced as well, but apparently this hasn't been accepted into the Standard yet.