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>