• Uncategorized

About c++ : Evaluation-order-of-function-arguments-and-default-arguments

Question Detail

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?

Question Answer

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().

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).

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.