http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60771
Bug ID: 60771 Summary: rejects-valid: static constexpr const reference initialization Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: filip.roseen at gmail dot com Created attachment 32550 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32550&action=edit testcase.cpp struct A { static constexpr int const& ref = 5; }; int main () { } ------------------------------------------------------------------ testcase.cpp:2:37: error: non-constant in-class initialization invalid for static member ‘A::ref’ static constexpr int const& ref = 5; ^ testcase.cpp:2:37: error: (an out of class initialization is required) testcase.cpp:2:37: error: ‘A::ref’ cannot be initialized by a non-constant expression when being declared ------------------------------------------------------------------ The snippet should be accepted, `int const&` is a literal-type and `5` sure is a constant expression suitable for initializing `ref` in the written context. [ Note: `gcc` correctly accepts `static constexpr int const& ref = 5;` if it appears outside of a class definition. ] [ Note: `clang` shows the correct behavior. ] ------------------------------------------------------------------ [basic.start.init]p2: > Variables with static storage duration (3.7.1) or thread storage > duration (3.7.2) shall be zero-initialized (8.5) before any other > initialization takes place. A constant initializer for an object o is > an expression that is a constant expression, except that it may also > invoke constexpr constructors for o and its subobjects even if those > objects are of non-literal class types [ Note: such a class may have a > non-trivial destructor — end note ]. > > Constant initialization is performed: > > — if each full-expression (including implicit conversions) that > appears in the initializer of a reference with static or > thread storage duration is a constant expression (5.19) and > the reference is bound to an lvalue designating an object > with static storage duration or to a temporary (see 12.2); > > </snip>