Namespaces
Variants
Actions

constinit specifier (since C++20)

From cppreference.com
< cpp‎ | language
 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications(until C++17*)
noexcept specifier(C++11)
Exceptions
Namespaces
Types
Specifiers
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
Special member functions
Templates
Miscellaneous
 
 

Contents

[edit]Explanation

The constinit specifier declares a variable with static or thread storage duration.

The constinit specifier can also be applied to structured binding declarations. In this case, constinit is also applied to the uniquely-named variable introduced by the declaration.

(since C++26)

If a variable is declared with constinit, its initializing declaration must be applied with constinit. If a variable declared with constinit has dynamic initialization (even if it is performed as static initialization), the program is ill-formed.

If no constinit declaration is reachable at the point of the initializing declaration, the program is ill-formed, no diagnostic required.

constinit cannot be used together with constexpr. When the declared variable is a reference, constinit is equivalent to constexpr. When the declared variable is an object, constexpr mandates that the object must have static initialization and constant destruction and makes the object const-qualified, however, constinit does not mandate constant destruction and const-qualification. As a result, an object of a type which has constexpr constructors and no constexpr destructor (e.g. std::shared_ptr<T>) might be declared with constinit but not constexpr.

constchar* g(){return"dynamic initialization";}constexprconstchar* f(bool p){return p ?"constant initializer": g();}   constinit constchar* c = f(true);// OK// constinit const char* d = f(false); // error

constinit can also be used in a non-initializing declaration to tell the compiler that a thread_local variable is already initialized, reducing overhead that would otherwise be incurred by a hidden guard variable.

extern thread_local constinit int x;int f(){return x;}// no check of a guard variable needed

[edit]Notes

Feature-test macroValueStdFeature
__cpp_constinit201907L(C++20)constinit

[edit]Keywords

constinit

[edit]Example

#include <cassert>   constexprint square(int i){return i * i;}   int twice(int i){return i + i;}   constinit int sq = square(2);// OK: initialization is done at compile time// constinit int x_x = twice(2); // Error: compile time initializer required   int square_4_gen(){static constinit int pow = square(4);   // constinit int prev = pow; // Error: constinit can only be applied to a// variable with static or thread storage durationint prev = pow; pow = pow * pow;return prev;}   int main(){assert(sq ==4); sq = twice(1);// Unlike constexpr this value can be changed later at runtimeassert(sq ==2);   assert(square_4_gen()==16);assert(square_4_gen()==256);assert(square_4_gen()==65536);}

[edit]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 2543C++20 the behavior was unclear if the variable declared with constinit
is dynamically initialized as part of static initialization
the program is ill-
formed in this case

[edit]See also

consteval specifier(C++20) specifies that a function is an immediate function, that is, every call to the function must be in a constant evaluation[edit]
constexpr specifier(C++11) specifies that the value of a variable or function can be computed at compile time[edit]
constant expression defines an expression that can be evaluated at compile time
constant initialization sets the initial values of the static variables to a compile-time constant
zero initialization sets the initial value of an object to zero
close