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.
Colour me surprised, but apparently C# does the "right" thing, and evaluates left to right:
void Main()
{
Console.WriteLine(Pop() - Pop()); // Prints -1
}
// Define other methods and classes here
bool switchVar = true;
int Pop()
{
int ret;
if (switchVar)
ret = 1;
else
ret = 2;
switchVar = !switchVar;
return ret;
}
I believe in C# the argument list is evaluated in order, from left to right.
No, C# doesn't do the same thing. It doesn't use evaluation boundaries the same way as C does, where the order of execution between the boundaries is undefined. The expression is evaluated left to right, just as you would expect.
If you are ever uncertain of the order of execution, or if you want to make the code clearer, you should use a local variable for an intermediate result. Local variables are very cheap to allocate as they are allocated on the stack, and in some cases the compiler is even able to put the variable in a register so that it's not allocated at all. Besides, depending on how the expression looks the compiler may need to use a local variable to store the intermediade result anyway.
From Fabulous Adventures In Coding: Precedence vs Associativity vs Order:
Another way to look at it is that the rule in C# is not "do the parentheses first", but rather to parenthesize everything then recursively apply the rule "evaluate the left side, then evaluate the right side, then perform the operation".
In C# it is left to right: http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx
Re: C++ order
Apparently this is because the compiler can't guarantee in which order the functions are evaluated (...why?)
Any particular compiler can guarantee the order. The problem is that the language spec does not specify an order, so each compiler can do whatever it wants. This means you have to add a sequence point between the two method calls if you want to guarantee ordering.