I have been trying to really master order of evaluation in complex expressions. As far as I can tell, the rules include operator precedence, operator associativity, left then right evaluation of binary operands, shortcut evaluation of certain logical operators, and ???
Is there a good write-up showing exactly how these rules play into each other?
Just as an example, && and < have lower precedence than ++, so why doesn't (i < 4 && ++i > 4) always increment i before < and && are evaluated at all? On the other hand, int index = 4; a[index] = index = index-2; changes a, not a, so  is evaluated before the operands of the right-hand =.
I can answer this stuff from a compiler (abstract syntax tree) perspective, but not from a language rules perspective.
Originally posted by Mike Gershman: Just as an example, && and < have lower precedence than ++, so why doesn't (i < 4 && ++i > 4) always increment i before < and && are evaluated at all?
Precedence order doesn't get applied across the entire expression. In other words, just because ++ has higher precedence than < doesn't mean ++ will be applied before all < operators in the entire expression -- only before <'s in the same subexpression.
In this case, the compiler first splits the above into two subexpressions ("i < 4" and "++i > 4") to be boolean anded after separate evaluation. They are evaluated in left-to-right order, so "i < 4" goes before "++i > 4". Of course, "++i" is evaluated before "> 4" due to precedence, but "i < 4" is done first due to LtR ordering.
Joined: Mar 13, 2004
Precedence order doesn't get applied across the entire expression. ... only ... in the same subexpression
Then why, in int index = 4; a[index] = index = index-2; does a, not a, get changed? = is right-associative.
JLS 15.7 may be the last word on evaluation order, but it's not easy to follow and it doesn't have much to say about how the different rules work together in a non-trivial expression. Is there another exposition available?
Peter van der Linden has a good explanation in his book Just Java 2. Unfortunately I can't quote it all here.
"There are three factors that influence the ultimate value of an expression in any algorithmic language, and they work in this order: precedence, associativity, and order of evaluation...."
"Precedence says that some operations bind more tightly than others...."
"Associativity is the tie breaker for deciding the binding when we have several operators of equal precedence strung together...."
"Order of evaluation tells us the sequence for each operator in which the operands are evaluated. In a string left-to-right language like Java, the order of evaluation tells us that in ( i = 2 ) * i++ , the left operand to the multiplication will be evaluated before the right operand, ..."
Seems like a good reason to write simple, readable code that doesn't require an expert to figure out what you're trying to do. [ December 26, 2004: Message edited by: Marilyn de Queiroz ]
JavaBeginnersFaq "Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
Yup, back when I was switching between languages that did or did not have any precedence rules, I got in the habit of splitting up the calculation or making the order explicit with parens any time I mix operators at all. I don't trust myself or the next reader (or the compiler, entirely) to get it right otherwise.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi