Question

Possible Duplicate:
Nonstatic member as a default argument of a nonstatic member function

Correct me if I am wrong, but the way I think default parameters work is this:

When the compiler sees the function call, it starts pushing the parameters onto the stack. When it runs out of parameters, it will start pushing the defaults onto the stack until all required parameters are filled (I know this is a simplification, since parameters are actually pushed from right to left, so it will start with the defaults, but the idea is the same).

If this is true, why can't member variables be used as defaults? It seems to me that since the compiler is pushing them as usual at the call site, it should be able to resolve them just fine!

EDIT Since it seems by the answers my question was misunderstood, let me clarify. I know this is the case, and I know what is and isn't allowed by the language. My question is why did the language designers choose to not allow this, since it seems to naturally work.

Was it helpful?

Solution

The essence of what you are asking can be distilled into this simple example

void foo(int a, int b = a);

This is not allowed in C++. C++ does not allow default arguments to depend on other parameters.

Using class members as default arguments is just a particular case of the above, since class members are accessed through this pointer and this pointer is just another hidden parameter of each non-static member function.

So, the question is really why

void foo(int a, int b = a);

is not allowed.

One obvious potential reason to disallow this is that it would impose additional requirements on the order of argument evaluation. As you know, in C++ the order of function argument evaluation is unspecified - the compiler can evaluate arguments in any order. However, in order to support the above default argument functionality the compiler would have to make sure that a is evaluated before b. This feels like an excessive requirement, which restricts the typical freedom of evaluation order that we are used to seeing in C++.

Note that this

int a;

void foo(int b = a);

is allowed in C++. And, obviously, it does not exhibit the aforementioned order of evaluation issue.

OTHER TIPS

I believe this are the most fitting paragraphs from the standard, especially §9:

8.3.6 Default arguments [dcl.fct.default]

§7 Local variables shall not be used in a default argument

§9 [...] Similarly, a non-static member shall not be used in a default argument, even if it is not evaluated, unless it appears as the id-expression of a class member access expression (5.2.5) or unless it is used to form a pointer to member (5.3.1).

This post lists all ways a default param can be set - Must default function parameters be constant in C++?

It's not difficult to workaround your need.

class A
{
    int a;
    public:
    void f(int i);

    void f()
    {
        f(a);
    }
};

gives you what you want.

Summarizing Nawaz excellent answer in the linked question: The call to void Foo::Bar(int a = this->member) really means void Foo__Bar(Foo* this, int a = this->member). Obviously the second argument cannot be evaluated before the first, which violates a C++ axiom that compilers can evaluate arguments in whatever order they like.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top