Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if two side effects on a assignment are unsequenced?

From §5.2.6/1 we have (emphasis is mine):

The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value — end note ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a complete object type. The value of the operand object is modified by adding 1 to it. The value computation of the ++ expression is sequenced before the modification of the operand object. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix ++ operator. — end note ] The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand. If the operand is a bit-field that cannot represent the incremented value, the resulting value of the bit-field is implementation-defined. See also [expr.add] and [expr.ass].

That is, the modification of the operand object is sequenced after the value computation of the ++ expression.

From §5.18/1 we have (emphasis is mine):

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator. — end note ]

assignment-expression:
      conditional-expression
      logical-or-expression assignment-operator initializer-clause
      throw-expression

assignment-operator: one of
      = *= /= %= += -= >>= <<= &= ^= |=

The assignment is also sequenced after the value computation of the right and left operands of the assignment operator.

Thus, if we consider the expression

i = i++;

we know from §5.2.6/1 that the side effect of the expression i++, on the RHS of this assignment expression is sequenced after the value computation of i++. And from §5.18/1 we know that the side effect corresponding to the assignment to i on the LHS of the assignment operator is sequenced after the value computation of the right and left operands of the assignment operator.

But how do I show that these two side effects are unsequenced, in order to prove that the expression i = i++; shows undefined behavior?

like image 619
Belloc Avatar asked Feb 08 '23 20:02

Belloc


1 Answers

First, if A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced (1.9/13). That's the definition of unsequenced. Second, if two side effects on a scalar object are unsequenced, the behavior is undefined (1.9/15). So unless you can find something that says that the post-increment and the assignment are sequenced (and you won't), the behavior is undefined.

like image 59
Pete Becker Avatar answered Feb 16 '23 02:02

Pete Becker