Why did `constexpr const int & a = 1;` fail in the block area?

N4527 7.1.5 [dcl.constexpr] p9

The constexpr specifier used in declaring an object declares the object as const. Such an object must be of literal type and must be initialized. If it is initialized by a constructor call, this call must be an expression constant (5.20). Otherwise, or if the constexpr specifier is used in the link description, each complete expression that appears in its initializer must be a constant expression.

5.20 [expr.const] p5

A constant expression is either an expression of the kernel constant glvalue whose value refers to an object that is the allowed result of a constant expression (as defined below) or an expression of a constant constant prvalue whose value is an object, where for this object and its subobjects:

- each non-static data element of a reference type refers to an object that is a valid result of a constant expression, and

- if the object or subobject has a pointer type, it contains the address of the object with a static storage duration, the address after the end of such an object (5.7), the address of the function, or the value of the null pointer.

An entity is a valid result of a constant expression if it is an object with a static storage duration that is either not a temporary object, or is a temporary object whose value satisfies the above restrictions, or it is a function.

void foo(){ constexpr const int &a = 1;//error constexpr static const int &b = 1;//ok in gcc 5.1.0 and clang 3.8.0 } 

Question: Why constexpr const int &a = 1; failed to scale block?

+6
source share
1 answer

This is described in the cwg 2005 bug report: invalid constexpr link initialization requirements that say (highlighted by me):

Consider an example of the type:

  constexpr int f() { return 5; } // function must be constexpr constexpr int && q = f(); // but result is not constant constexpr int const & r = 2; // temporary is still not constant int main() { q = 11; // OK const_cast< int & >( r ) = 3; // OK (temporary object is not ROMable) constexpr int && z = 7; // Error? Temporary does not have static storage duration? } 

A reference to constexpr must be initialized with a constant expression (7.1.5 [dcl.constexpr], clause 9), however it can refer to a mutable temporary object. Such a temporary guaranteed static initialization, but it is not writable.

The non-constant constexpr reference initialized with the lvalue expression is useful because it indicates that the underlying storage link may be statically initialized or that no base storage is required at all.

When the initializer is temporary, the search for its address is trivial. There is no reason to declare any intentions to the address. On the other hand, an initial value is provided, and it is also required to be a constant expression, although it has never been treated as a constant.

The situation is worse for local constexpr links. The initializer generates a temporary expression when the declaration is executed. Temporary is a locally restricted, unique object. This displays constexpr pointless, because although address computation is trivial, it still needs to be done dynamically.

C ++ 11 constexpr constants require initialization by reference of constant expressions that were supposed to “assign an object with a static storage duration or function” (C ++ 11 5.20 [expr.const], clause 3). Temporary with automatic storage duration provided by the link does not meet this requirement.

C ++ 14 removes reference constant expressions and static storage requirement, which ensures the correct operation of the program with the explicitly defeated constexpr constructor. (GCC and Clang currently provide C ++ 11.)

Proposed resolution: a temporary reference to a constexpr reference must itself be constexpr, implying a const-qualified type. prohibit the linking of constexpr links to temporary ones, if both of them do not have a static storage period. (In the local area, the static specifier captures well.)

The answer is that this is already prohibited by 5.20 paragraph 4:

This problem has already been discussed in paragraph 5.20 [expr.const], which includes transformations and time data in the analysis.

+4
source

All Articles