I was just surprised to see that on GCC (4.3.2) the left hand side of an assignment expression might be evaluated before the right hand side:
int x,y;
int& getX()
{
std::cout << "getX\n";
return x;
}
int& getY()
{
std::cout << "getY\n";
return y;
}
void test()
{
x = 3; y= 4;
getX() = getY();
}
Calling test() outputs
getX
getY
Whereas on MSVC, the opposite order is used. Is there any definition by the standard about this?
Yes and no.
In essence, the Standard defines that it is unspecified, and only guarantees that the arguments will be ready when the function is called.
EDIT: even worse, the expressions evaluation could be interleaved. See example.
Basically you should just remember that whenever you have a function, and a = b
is a function call: operator=(a , b)
, then the order in which the arguments of the functions are evaluated is unspecified.
GCC usually goes right to left, but the optimizer could decide that sometimes left to right is faster for example. It could even change at runtime, though for practical reasons I have never seen such an implementation.
EDIT:
Since the Standard does not promise a particular ordering or even atomic execution, the following statement:
test(foo() + bar(), fud());
Can result in the 4 following call sequences:
which are more or less "expected" when you understand the "unspecified" term and its consequences... but it can also lead to the 2 following sequences:
which are much more surprising. This is interleaving.
I have left out the +
operation here, which can only be executed once foo
and bar
have been computed, but may be executed before or after fud
.
If the functions are pure, or have completely disjoint operation sets, it should not matter. Sometimes there are some suprising side effects though, and it may even lead to memory leaks...
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