Speaking in the context of the C++11 standard (which no longer has a concept of sequence points, as you know) I want to understand how two simplest examples are defined.
int i = 0;
i = i++; // #0
i = ++i; // #1
There are two topics on SO which explain those examples within the C++11 context. Here it was said that #0
invokes UB and #1
is well-defined. Here it was said that both examples are undefined. This ambiguity confuses me much. I've read this well-structured reference three times already but the topic seems to be way too complicated for me.
.
Let's analyze the example #0
: i = i++;
.
Corresponding quotes are:
The value computation of the built-in postincrement and postdecrement operators is sequenced before its side-effect.
The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)
If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
As I get it, the side effect of the assignment operator is not sequenced with side effects of it's left and right arguments. Thus the side effect of the assignment operator is not sequenced with the side effects of i++
. So #0
invokes an UB.
.
Let's analyze the example #1
: i = ++i;
.
Corresponding quotes are:
The side effect of the built-in preincrement and predecrement operators is sequenced before its value computation (implicit rule due to definition as compound assignment)
The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)
If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.
I can not see, how this example is different from the #0
. This seems to be an UB for me for the very same reason as #0
. The side effect of assignment is not sequenced with the side effect of ++i
. It seems to be an UB. The topic liked above says it is well-defined. Why?
.
Question: how can I apply quoted rules to determine the UB of the examples. An as simple as possible explanation would be greatly appreciated. Thank you!
See Question&Answers more detail:os