Multiple assignment on one line not working as expected

后端 未结 3 1596

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 thi

相关标签:
3条回答
  • 2021-01-17 08:43

    The order of evaluation is defined in chapter 15 of the JLS. Item 15.7.1 says:

    If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation.

    To explain further, they have two examples of computations that involve assignments. Here the assignment is on the left hand of the operator:

    int i = 2;
    int j = (i=3) * i;
    System.out.println(j);
    

    And they specifically say that the result is 9 and is not allowed to be 6. That is, the (i=3) is both calculated as 3 and i is assigned 3 before being multiplied with itself.

    But in the second example:

        int a = 9;
        a += (a = 3);  // first example
        System.out.println(a);
        int b = 9;
        b = b + (b = 3);  // second example
        System.out.println(b);
    

    The JLS specifies that both prints should produce 12, and are not allowed to produce 6. That is, because the assignment to b is on the right side, the value of the left b (or the implicit left a in the += operation), the value before that assignment is fetched and saved first, and only then the operation inside the parentheses is performed.

    Internally, expressions are broken down into JVM operations that push and pop values onto an "operand stack". If you think about it like that - that in b = b + (b=3) The value of b is first pushed onto the operand stack, then the (b=3) is performed and its value is then added to the value popped from the stack (old value of b), it will make sense. At this point, the left hand b just stands for "What the value of b was when it was pushed on the stack" and not for the "current value of b".

    0 讨论(0)
  • 2021-01-17 08:43

    Lets divide and compute.

    The innermost parenthesis executes first and after all the parenthesis resolved, then the expression executes from left to right.

    x ^= (y ^= (x ^= y));   // initial statement
    
    x = x^(y = y^ (x = x^y)); //equals to 
    
    () have the highest precedence
    
    x = x^(y = y^ (x = 3^4)); // first highest precedence () 
    
    x = x^(y = y ^ (x = 7)); // still the first x is 3
    
    x = 4 ^(y = 3 ^ (x = 7));  // now 3 ^ 7 =4
    
    x = 4 ^ 4;  // now  3 ^ 7 =4
    
    x= 0;
    
    0 讨论(0)
  • 2021-01-17 08:44

    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.

    0 讨论(0)
提交回复
热议问题