Reputation: 476930
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
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