constant initialization

From cppreference.com
< cpp‎ | language

Sets the initial values of the static constants

Syntax

static T & ref = constexpr; (1)
static T object = constexpr; (2)

Explanation

Constant initialization is performed after (until C++14)instead of (since C++14) zero initialization of the static and thread-local objects and before all other initialization. Only the following variables are constant initialized:

1) Static or thread-local references, if it is bound to static glvalue, to a temporary object (or its subobject), or to a function. and if every expression (including implicit conversions) in the initializer of the reference is a constant expression.
2) Static or thread-local object of class type that is initialized by a constructor call, if the constructor is constexpr and all constructor arguments (including implicit conversions) are constant expressions, and if the initializers in the constructor's initializer list and the brace-or-equal initializers of the class members only contain constant expressions.
3) Static or thread-local object (not necessarily of class type), that is not initialized by a constructor call, if the object is value-initialized or if every expression in its initializer is a constant expression.

The effects of constant initialization are the same as the effects of the corresponding initialization, except that it's guaranteed that it is complete before any other initialization of a static or thread-local object begins, and it may be performed at compile time.

Notes

The compiler is permitted to initialize other static and thread-local objects using constant initialization, if it can guarantee that the value would be the same as if the standard order of initialization was followed.

Example

#include <iostream>
#include <array>
 
struct S {
    static const int c;
};
const int d = 10 * S::c; // not a constant expression: S::c has no preceding
                         // initializer, this initialization happens after const
const int S::c = 5;      // constant initialization, guaranteed to happen first
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK: S::c is a constant expression
//  std::array<int, d> a2;    // error: d is not a constant expression
}

Output:

d = 50

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 2026 C++14 zero-init was specified to always occur first, even before constant-init no zero-init if constant init applies

See also