c++constantslanguage-lawyerlocal-variablesfunction-declaration

Local scope constant as function's default argument


Can function declaration in a function scope have a locally defined constant as default argument?

For example,

void f(int) {}

int main() {
    constexpr int c = 1;
    void f(int = c);
    f();
}

GCC dislikes it, saying

error: local variable 'c' may not appear in this context

MSVC behaves similarly:

error C2587: 'c': illegal use of local variable as default parameter

But Clang accepts it just fine. Online demo: https://gcc.godbolt.org/z/9vWoK6TEz

Which implementation is correct here?


Solution

  • Clang is correct, there's nothing preventing the use of c as a default argument. Based on the diagnostics, GCC and MSVC appear to be trying to implement the following note:

    A local variable cannot be odr-used ([basic.def.odr]) in a default argument.

    However, since c is a constexpr variable, reading from it doesn't constitute an odr-use. As c is not being odr-used here, the note doesn't apply.

    Note that if you do try to odr-use c in a default argument, say, by taking a reference to it

    void f(const int& = c);  // error: default argument references local variable 'c' of enclosing function
    

    or by making c not constexpr, Clang rejects it.