I just tested the following code:
int x = 90;
x = x - (x = x - 1);
System.out.print(x);
It prints 1.
As far as I understand, things go in the following order:
x - 1
is computed and stored to a temporary variable in memory.x
is assigned the result from the temporary variable from item 1.x - the new value of x
is calculated.x
;I don't understand why x
from which we subtract the result of item 2 still has initial value after item 2. What am I missing?
From https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
You are doing 90 - (90 - 1)
=> 1
It's important to not confuse precedence with order of evaluation. They are related but not the same.
EDIT
As @ruakh points out, the JLS spec put it differently to the tutorial above.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7.
The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
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.
If evaluation of the left-hand operand of a binary operator completes abruptly, no part of the right-hand operand appears to have been evaluated.
Rather than say the assignment is evaluated right to left, it treats assignment as first a store of the variable to be updated, then an evaluation of the value and finally an assignment.
We start with:
int x = 90;
x = x - (x = x - 1);
The first assignment operator = has low precedence, so the right side is evaluated first.
The right side of x = x - (x = x - 1) is x - b where b is (x = x - 1)
This right side is evaluated left to right, so it becomes 90 - b
Then b, which is (x = x - 1), is evaluated. Once again the assignment operator has lowest precedence, so it becomes (x = 90 - 1) or (x = 89)
Substituting back, we have 90 - (x = 89) which is 90 - 89 which is 1. Finally, the first assignment operator is evaluated and x becomes 1. You'll notice that the other assignment operator (x = 89) had no effect on the overall operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With