Search code examples
c++scopec++14overloadingdefault-value

In C++, does the scope of a named parameter include the expression for its default value?


Example: Is this legal C++14?

#include <iostream>

static int d() {
    return 42;
}

static int e(int d = d()) {
    return d;
}

int main() {
    std::cout << e() << " " << e(-1) << std::endl;
}

g++ 5.4 with -std=c++14 likes it, but clang++ 3.8 with -std=c++14 complains:

samename.cxx:3:23: error: called object type 'int' is not a function or function pointer
static int e(int d = d()) {return d;}
                     ~^

Solution

  • From basic.scope.pdecl/1:

    The point of declaration for a name is immediately after its complete declarator and before its initializer (if any), except as noted below.

    Example:

    unsigned char x = 12;
    { unsigned char x = x; }
    

    Here the second x is initialized with its own (indeterminate) value.

    Clang is consistent with this section of the standard. GCC only seems to apply it in {block}.

    Given:

    constexpr int d() {return 42;}
    

    The following fails in Clang, but works in GCC:

    static int e(int d = d()) {return d;}
                 // This ^^d should refer to the new name that shadows ::d()
    

    The following fails both in Clang and GCC:

    void func(){
        int d = d();
             // ^^d here refers to the new name that shadowed ::d();
     }