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
?
All constexpr variables are const . A variable can be declared with constexpr , when it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as constexpr .
Even though try blocks and inline assembly are allowed in constexpr functions, throwing exceptions or executing the assembly is still disallowed in a constant expression.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later. So, what does constexpr mean?
The only types usable within a constexpr context are literal types. A constant expression or constexpr function may also not invoke a non constexpr function. The constexpr keyword implies inline. Performing computations at compiletime can have many advantages over doing them at runtime.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With