Kerrek SB
Kerrek SB

Reputation: 476930

Mixing constexpr declarations and const definitions

I came across the following situation:

struct Foo
{
    static constexpr char s[] = "Hello world";
};

const char Foo::s[];

This code snippet compiles with Clang 3.7 (with -std=c++11 and -std=c++14), but GCC (4.8, 6.0, same language settings) gives the error I would have expected:

GCC 4.8:

in.cpp:6:19: error: redeclaration ‘Foo::s’ differs in ‘constexpr’
 const char Foo::s[];
                   ^
in.cpp:3:27: error: from previous declaration ‘Foo::s’
     static constexpr char s[] = "Hello world";
                           ^
in.cpp:6:19: error: declaration of ‘constexpr const char Foo::s [12]’ outside of class is not definition [-fpermissive]
 const char Foo::s[];

GCC 6.0:

‘constexpr’ needed for in-class initialization of static data member ‘const char Foo::s [12]’ of non-integral type [-fpermissive]

I found this old question that seems to discuss mixing constexpr and const, but it focusses on whether initializers are constant expressions, rather on whether definition and declaration can differ with regard to constness.

Is it allowed to provide the definition for a constexpr T static data member as a const T?

Upvotes: 18

Views: 626

Answers (1)

Columbo
Columbo

Reputation: 60969

Your code is well-formed. The constexpr-specifier is not itself part of the type but adds const ([dcl.constexpr]/9), which is present in your second declaration. Although different declarations of one function (or function template) have to agree in constexpr-ness as per [dcl.constexpr]/1, no such rule exists for variable declarations.

See bug #58541, which basically uses your example.

Upvotes: 13

Related Questions