问题
I recently ran across the following situation:
#include <iostream>
int *p = 0;
int f() {
p = new int(10);
return 0;
}
void g(int x, int *y = p) {
std::cout << y << std::endl;
}
int main() {
g(f());
}
This is quite subtle, since you usually don't expect the default arguments to change during their evaluation for the function call. I had to take a look at the assembly to spot this error.
Now my question is: Is this really undefined behavior, since there aren't any guarantees concerning the evaluation order of function arguments?
回答1:
The order of evaluation (i.e. determining the value) of function arguments is not specified. The compiler is free to execute them in any order, and even intermingled if there are no other factors stopping it from doing so.
Evaluation of default arguments happens in the context of the caller, not the callee. So the call to f() is necessary for one argument, and reading the global variable p for the other. Which order this happens in is not specified, so the global could be read before or after the call to f().
回答2:
If I understand it correctly, your call
g(f());
is equivalent to
g(f(), p);
due to the declaration
void g(int x, int *y = p);
And arguments to the g
function , f()
and p
, can be evaluated in any order, so you can get g
called with y
assigned either zero (if p
is evaluated first, then it returns its initial value) or the newly allocated array pointer (if f()
is evaluated first and it assigns a new value to p
as its side effect).
来源:https://stackoverflow.com/questions/32222416/evaluation-order-of-function-arguments-and-default-arguments