This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Voted into the WP at the September, 2008 meeting (resolution in paper N2757).]
Given this literal type,
struct X { constexpr X() { } };
and this definition,
static X x;
the current specification does not require that x be statically initialized because it is not “initialized with a constant expression” (6.9.3.1 [basic.start.main] paragraph 1) .
Lawrence Crowl:
This guarantee is essential for atomics.
Jens Maurer:
Suggestion:
A reference with static storage duration or an object of literal type with static storage duration can be initialized with a constant expression (7.7 [expr.const]) or with a constexpr constructor; this is called constant initialization.
(Not spelling out “default constructor” makes it easier to handle multiple-parameter constexpr constructors, where there isn't “a” constant expression but several.)
Peter Dimov:
In addition, there is a need to enforce static initialization for non-literal types: std::shared_ptr, std::once_flag, and std::atomic_* all have nontrivial copy constructors, making them non-literal types. However, we need a way to ensure that a constexpr constructor called with constant expressions will guarantee static initialization, regardless of the nontriviality of the copy constructor.
Proposed resolution (April, 2008):
Change 6.9.3.2 [basic.start.static] paragraph 1 as follows:
...A reference with static storage duration and an object of trivial or literal type with static storage duration can be initialized with a constant expression (7.7 [expr.const]); thisIf a reference with static storage duration is initialized with a constant expression (7.7 [expr.const]) or if the initialization of an object with static storage duration satisfies the requirements for the object being declared with constexpr (9.2.6 [dcl.constexpr]), that initialization is called constant initialization...
Change 8.8 [stmt.dcl] paragraph 4 as follows:
...A local object of trivial or literal type (6.8 [basic.types]) with static storage duration initialized with constant-expressions is initializedConstant initialization (6.9.3.2 [basic.start.static]) of a local entity with static storage duration is performed before its block is first entered...
Change 9.2.6 [dcl.constexpr] paragraph 7 as follows:
A constexpr specifier used in an object declaration declares the object as const. Such an object shall be initialized, and every expression that appears in its initializer (9.4 [dcl.init]) shall be a constant expression. Every implicit conversion used in converting the initializer expressions and every constructor call used for the initialization shall be one of those allowed in a constant expression (7.7 [expr.const])...
Replace 9.4.2 [dcl.init.aggr] paragraph 14 as follows:
When an aggregate with static storage duration is initialized with a brace-enclosed initializer-list, if all the member initializer expressions are constant expressions, and the aggregate is a trivial type, the initialization shall be done during the static phase of initialization (6.9.3.2 [basic.start.static]); otherwise, it is unspecified whether the initialization of members with constant expressions takes place during the static phase or during the dynamic phase of initialization.[Note: The order of initialization for aggregates with static storage duration is specified in 6.9.3.2 [basic.start.static] and 8.8 [stmt.dcl]. —end note]
(Note: the change to 6.9.3.2 [basic.start.static] paragraph 1 needs to be reconciled with the conflicting change in issue 684.)