0

I tried "swap variable in java without temp" in Java and I found something that bothers me:

int a = 1, b = 2;
b^= a ^= b ^= a;
System.out.println(a + " vs " + b);

The output shows

2 vs 0


However if I separate the leftmost assignment as a individual statement:

int a = 1, b = 2;
a ^= b ^= a;
System.out.println(a + " vs " + b);
b^=a;
System.out.println(a + " vs " + b);

The output is

2 vs 3
2 vs 1

Now the output is as expected.
In C++, the evaluation is ensured from right to left. What the difference, in terms of language spec, tells Java could lead such expected result?

Leo Lai
  • 863
  • 8
  • 17

1 Answers1

4

According to the JLS, x ^= y is equivalent to x = (x) ^ (y) (there's also a cast in there, but if you're dealing with ints, the cast doesn't matter anyway). So this:

b ^= a ^= b ^= a;

is equivalent to

    b = (b) ^ (a = (a) ^ (b = (b) ^ (a)));
//      ^^^

In Java, arguments to an operator are always evaluated left to right. So the b that I pointed to in the above is the original value of b, since it's evaluated before the assignment to b in the right part of the expression. That means the expression is not equivalent to

b ^= a;
a ^= b;
b ^= a;   

since the third statement uses the new value of b as the left operand to ^.

ajb
  • 31,309
  • 3
  • 58
  • 84