I am preparing for a Java exam and I am trying to understand operator precedence and compound assignment operators in depth. I played around with a few expressions which use compound assignment during the evaluation of an expression. However, I do not fully understand why these give the result that they do.
int a = 3, b = 0;
b += a *= (a *= (a *= 2));
// Result: a=54, b=54
What I expected:
//innermost expression evaluated first
//a = a * 2 = 6, so a assigned to 6; 6 returned
//Then next one is evaluated as:
//a = a * 6 = 36, so a assigned to 36; 36 returned
//The outermost expression evaluated as:
//a = 36 * 36 = 1296
//Finally, b = b + 1296, so b = 1296.
Instead, a = 54 is the answer. So during all three evaluations of "a *= 2", the old value of a is used instead, so the final answer is a = 3 * 3 * 3 * 2 = 54.
However, this expression behaves differently:
int c = 1, d = 0;
d += (c *= 2) + (c *= 5) + (c += 100);
// Result: c=110, d=122
If here the old value of c was used we would end up with c = 101 and d = 108. Instead, we end up with c = 2 * 5 + 100 = 110; meaning that in each of those evaluations of "c *= ..", the new (updated) value of c was used each time.
Question: why in the first example the original value of a gets used in the compound assignments, but in the second example the updated value of c gets used?
According to §15.26.2. Compound Assignment Operators:
At run time, the expression is evaluated in one of two ways. [...]
- the value of the left-hand operand is saved and then the right-hand operand is evaluated
This explains the behavior for the first expression.
According to §15.18. Additive Operators:
The additive operators have the same precedence and are syntactically left-associative (they group left-to-right).
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
Thus, the second expression is evaluated from left to right and side effects of updating the variables occur in that order.