Constant initialization

From cppreference.com
< cpp‎ | language
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous

Sets the initial values of the static variables to a compile-time constant.

Explanation

Constant initialization is performed in the following cases:

  • Initializing an object of POD type with static storage duration with a constant expression.
(until C++11)
  • an lvalue designating an object with static storage duration
  • a temporary object
  • a subobject of a temporary object
  • a function
  • Initializing an object with static or thread storage duration, and one of the following conditions is satisfied:
  • If the object is initialized by a constructor call, where the initialization full-expression is a constant expression, except that it may also invoke constexpr constructors for the object and its subobjects (even if those objects are of non-literal
  • Otherwise, either the object is value-initialized or every full-expression that appears in its initializer is a constant expression.
(since C++11)
(until C++17)
(since C++17)
(until C++20)
(since C++20)

The effects of constant initialization are the same as the effects of the corresponding initialization, except that it is guaranteed that it is complete before any other initialization of a staticor thread-local(since C++11)

Notes

The compiler is permitted to initialize other static and thread-local (since C++11)

Constant initialization usually happens when the program loads into memory, as part of initializing the program's runtime environment.

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 441 C++98 references could not be constant initialized made constant initializable
CWG 1489 C++11 it was unclear whether value-initializing
an object can be a constant initialization
it can
CWG 1747 C++11 binding a reference to a function could not be constant initialization it can
CWG 1834 C++11 binding a reference to an xvalue could not be constant initialization it can

See also