First will invoke undefined behavior in both C99 and C11.
In C99, it can be understood as; they will invoke undefined behavior because of the lack of the sequence points.
C-faq:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
Explanation:
The first one is modifying a
twice between two sequence points and hence behavior is undefined as per statement: Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. That's it (no need to think about b
).
C11 documentation says:
6.5 Expressions (p2):
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.84)
In (a) ^= (b) ^= (a) ^= (b)
, side effect on a
is unsequenced and hence invoke undefined behavior. It should be noted that C11 6.5 p1 says that:
[...] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.
This guarantees that in
(a) ^= (b) ^= (a) ^= (b)
| | | |
1 2 3 4
all subexpressions 1, 2, 3 and 4 are guaranteed to be computed before the result computation of left most ^=
operator. But, this doesn't guarantee that side effect of expression 3 is guaranteed before the value computation of the result of the left most ^=
operator.
1. Emphasis is mine.