javaoperator-precedencecompound-assignment

Using multiple compound assignments in a single expression


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?


Solution

  • 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).

    And §15.7. Evaluation Order:

    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.