Swap integers with XOR on the same line. Is this really allowed in C ++ 11?

I still could not clearly understand whether the expression x ^= y ^= x ^= y; valid in C ++ 11 (as this thread says) or leads to undefined behavior?

The reasons indicated by the link seem convincing, but clang throws a warning :

warning: disjoint modification and access to "x" [-University]

In addition, if both versions:

 x ^= y ^= x ^= y; // (1) x = x ^ (y = y ^ (x = (x ^ y))); // (2) 

considered equivalent (and clearly defined in C ++ 11), why does it give different results ( first , second )?

In addition, it should be noted that gcc gives a warning about a sequence point only in the second version of the code.

+6
source share
1 answer

Assignment operator (=) and all assignment operators group from right to left. [..]
The behavior of an expression of the form E1 op = E2 equivalent to E1 = E1 op E2 , except that E1 is evaluated only once.

So your code is equivalent

 x = x ^ (y ^= (x ^= y))); 

... with x is evaluated only once at x = x ... Unfortunately, for xor's, evaluating operands does not matter. I.e

Except where noted, evaluations of the operands of individual operators and subexpressions of individual expressions are not affected.

applies. But now we have a problem:

  x = x ^ (y ^= (x ^= y))); // * ****** // | | // | Side effect // Value computation 

The calculation of the value (which is implied in the singular estimate of x for the two left x ), and the side effect is independent of each other, so we induce UB:

If the side effect of a scalar object is independent of another side effect on the same scalar object or calculating a value using the value of the same scalar object, the behavior is undefined.

+11
source

Source: https://habr.com/ru/post/984349/


All Articles