Take the following C code (K&R pg. 77) :
push(pop() - pop()); /* WRONG */
The book says that since -
and /
Order of evaluation is well-defined in C# in all cases, and is left-to-right. From C# language spec (§7.3):
The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators (§7.2.1). Operands in an expression are evaluated from left to right. For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. This is separate from and unrelated to operator precedence
In case of C++, it's not that the order couldn't be defined; it's that allowing the order to be undefined allows the compiler to better optimize code.
The book says that since - and / are not commutative operators, the order in which the 2 pop functions are evaluated is necessary (obviously, to get the correct result)...and thus you have to put the result of the first function in a variable first and then proceed with the arithmetic.
That's not quite correct. K&R allowed rearrangement of commutative operators (done away with in ANSI C). Since suibtraction is not commutative, it is not re-arrangeable...under that rule, at least.
(Un)fortunately, C also doesn't define the order of evaluation (outside of a fairly small scope) - which means the compiler can call those functions in any order (as long as the result of pop() - pop()
is fully evaluated before calling push()
)
Which - in this case, results in the same problem - but for a different reason.