Search code examples
javavariablesvariable-assignmentbitwise-operatorsxor

Multiple assignment on one line not working as expected


I'm trying to swap two ints - x and y in the example, and do it in one line without a library function.

So I started with this:

int x = 4;
int y = 3;

System.out.println(x);
System.out.println(y);

x ^= y;

System.out.println(x);
System.out.println(y);

y ^= x;

System.out.println(x);
System.out.println(y);

x ^= y;

System.out.println(x);
System.out.println(y);

The output was 4, 3, 7, 3, 7, 4, 3, 4 as expected. All good so far.

Next up was this:

int x = 4;
int y = 3;

System.out.println(x);
System.out.println(y);

y ^= (x ^= y);

System.out.println(x);
System.out.println(y);

x ^= y;

System.out.println(x);
System.out.println(y);

The output was 4, 3, 7, 4, 3, 4 as expected once again. Still good so far.

Then finally this:

int x = 4;
int y = 3;

System.out.println(x);
System.out.println(y);

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

System.out.println(x);
System.out.println(y);

At this stage the output became 4, 3, 0, 4. Now I know that the 0 is a result of 4 ^ 4 because the x assignment wasn't complete at that time - why is this happening? Why doesn't the x ^= y actually assign 7 to the x variable so that it becomes 7 ^ 4 for the last assignment?


Solution

  • Let's try to expand your last expression.

    It evaluates to,

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

    Note that expressions are evaluated from left to right,

    it becomes,

    x = 4 ^ (y = 3 ^ (x = 4 ^ 3));
    

    Now, the problem has become obvious. Right?

    Edit:

    To clear come confusion, let me try to explain what I mean by evaluating from left to right.

    int i = 1;
    s = i + (i = 2) + i;
    

    Now, the expression will evaluate to,

    s = 1 +    2    + 2;
    

    Notice that i on the left of assignment was 1, but on the right of assignment (and on the assigment) was evaluated to 2, because the evaluation is from left to right, when it came to the 2nd and 3rd part of the expression, is value was 2.