According to this table, ++
has right to left associativity. So, I run this code:
int a = 5;
++a + ++a * ++a
and expect the expression to be 50
(as 8 + 7 * 6
, increment starts from right to left). But the expression is evaluated from left to right (6 + 7 * 8
) by Eclipse, and gives result as 62
. I am new to this associativity in Java, and must be missing something obvious. Please help me understand this strange behavior.
EDIT: Thank you for your answers, but I have one more question now. It is that, as seen from @bizclop's code and tree answer, it is obvious that the associativity for ++
doesn't matter. Then, is there any use case for this associativity of ++
/--
?
Associativity is the left-to-right or right-to-left order for grouping operands to operators that have the same precedence. An operator's precedence is meaningful only if other operators with higher or lower precedence are present. Expressions with higher-precedence operators are evaluated first.
b = a; Here, the value of a is assigned to b , and not the other way around. It's because the associativity of the = operator is from right to left. Also, if two operators of the same precedence (priority) are present, associativity determines the direction in which they execute.
The associativity of operators is decided by checking the Type Of Recursion in the production. If the production has left recursion, then the operator is left associative. If the production has right recursion, then the operator is right associative.
There are two different things mixed up here: expression parsing and expression evaluation.
Let's start with the expression: ++a + ++a * ++a
. What do we first have to do with it? Since operators +
and *
need two operands and ++
needs one, we have to figure out which operand goes with which operation. This is the expression parsing step, where precedence/associativity are applied.
++
has the highest precedence, so we can rewrite our expression as (++a) + (++a) * (++a)
*
, so again we can add parentheses: (++a) + ((++a) * (++a))
+
, the lowest precedence of all, so for the sake of symmetry we can write: ((++a) + ((++a) * (++a)))
Note that we can represent this neatly as a tree:
+
/ \
++ *
| | \
a ++ ++
| |
a a
So this is our evaluation tree based on precedence and associativity.
Note that in this case associativity didn't matter at all as all the operators had different precedence. Had our expression been
4 - 1 - 3 + 2
, it would've been important to use associativity to reach(((4 - 1) - 3) + 2)
, as+
and-
have the same precedence.
Now comes the next step, evaluation. Evaluation always happens from left to right (even for assignments, though the rules are a bit quirky), but it happens left-to-right using the tree we've just built.
+
operator, as it's on the top.++a
on the left side of the +
operator, (6)
*
operation.++a
, (7)
++a
(8)
*
operation evaluated), (56)
...and we're done.
TL;DR: Precedence and associativity determine where to put parentheses but evaluation is always left-to-right.
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.
It is because multiplication operator *
has higher precedence over the addition +
operator.
The computation will be ++a + (++a * ++a) = 6 + 7 * 8
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