Constant initialization

From cppreference.com
< cpp‎ | language
 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++20)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
decltype (C++11)
auto (C++11)
alignas (C++11)
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
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
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.

Syntax

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

Explanation

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

1) Static or thread-local (since C++11) references, if it is bound to static glvalue, to a temporary object (or its subobject) (since C++11), 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 (since C++11) object of a PODType (until C++11) (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.
3) 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.
(since C++11)

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 (since C++11) object begins, and it may be performed at compile time.

Notes

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

In practice, constant initialization is performed at compile time, and pre-calculated object representations are stored as part of the program image (e.g. in the .data section). If a variable is both const and constant-initialized, its object representation may be stored in a read-only section of the program image (e.g. the .rodata section)

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 2026 C++98 zero-init was specified to always occur first, even before constant-init no zero-init if constant init applies

See also