This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


688. Constexpr constructors and static initialization

Section: 6.9.3.2  [basic.start.static]     Status: CD1     Submitter: Peter Dimov     Date: 26 March, 2008

[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):

  1. Change 6.9.3.2 [basic.start.static] paragraph 1 as follows:

  2. ...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]); this If 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...
  3. Change 8.8 [stmt.dcl] paragraph 4 as follows:

  4. ...A local object of trivial or literal type (6.8 [basic.types]) with static storage duration initialized with constant-expressions is initialized Constant initialization (6.9.3.2 [basic.start.static]) of a local entity with static storage duration is performed before its block is first entered...
  5. Change 9.2.6 [dcl.constexpr] paragraph 7 as follows:

  6. 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])...
  7. Replace 9.4.2 [dcl.init.aggr] paragraph 14 as follows:

  8. 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.)