Namespaces
Variants

constinit specifier (since C++20)

From cppreference.net
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

Inhaltsverzeichnis

Erklärung

Der constinit -Spezifizierer deklariert eine Variable mit statischer oder Thread- Speicherdauer .

Der constinit -Spezifizierer kann auch auf strukturierte Bindungen angewendet werden. In diesem Fall wird constinit ebenfalls auf die durch die Deklaration eingeführte eindeutig benannte Variable angewendet.

(seit C++26)

Wenn eine Variable mit constinit deklariert wird, muss ihre initialisierende Deklaration mit constinit versehen werden. Wenn eine mit constinit deklarierte Variable eine dynamische Initialisierung aufweist (selbst wenn sie als statische Initialisierung durchgeführt wird ), ist das Programm fehlerhaft.

Wenn keine constinit Deklaration an der Stelle der initialisierenden Deklaration erreichbar ist, ist das Programm fehlerhaft, keine Diagnose erforderlich.

constinit kann nicht zusammen mit constexpr verwendet werden. Wenn die deklarierte Variable eine Referenz ist, entspricht constinit constexpr . Wenn die deklarierte Variable ein Objekt ist, erfordert constexpr , dass das Objekt statische Initialisierung und konstante Destruktion haben muss und qualifiziert das Objekt als const, während constinit weder konstante Destruktion noch Const-Qualifizierung erfordert. Daher kann ein Objekt eines Typs mit constexpr-Konstruktoren, aber ohne constexpr-Destruktor (z.B. std:: shared_ptr < T > ) mit constinit deklariert werden, aber nicht mit constexpr .

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

constinit kann auch in einer nicht-initialisierenden Deklaration verwendet werden, um dem Compiler mitzuteilen, dass eine thread_local Variable bereits initialisiert ist, wodurch Overhead reduziert wird , der sonst durch eine versteckte Guard-Variable entstehen würde.

extern thread_local constinit int x;
int f() { return x; } // keine Überprüfung einer Guard-Variable erforderlich

Hinweise

Feature-Test-Makro Wert Std Feature
__cpp_constinit 201907L (C++20) constinit

Schlüsselwörter

constinit

Beispiel

#include <cassert>
constexpr int square(int i)
{
    return i * i;
}
int twice(int i)
{
    return i + i;
}
constinit int sq = square(2);    // OK: Initialisierung erfolgt zur Compile-Zeit
// constinit int x_x = twice(2); // Fehler: Compile-Zeit-Initialisierer erforderlich
int square_4_gen()
{
    static constinit int pow = square(4);
    // constinit int prev = pow; // Fehler: constinit kann nur auf eine
                                 // Variable mit statischer oder Thread-Speicherdauer angewendet werden
    int prev = pow;
    pow = pow * pow;
    return prev;
}
int main()
{
    assert(sq == 4);
    sq = twice(1); // Im Gegensatz zu constexpr kann dieser Wert später zur Laufzeit geändert werden
    assert(sq == 2);
    assert(square_4_gen() == 16);
    assert(square_4_gen() == 256);
    assert(square_4_gen() == 65536);
}

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 2543 C++20 das Verhalten war unklar, wenn die mit constinit
deklarierte Variable als Teil der statischen Initialisierung dynamisch initialisiert wird
das Programm ist in diesem Fall fehler-
haft

Siehe auch

consteval Spezifizierer (C++20) spezifiziert, dass eine Funktion eine Immediate-Funktion ist, d.h. jeder Aufruf der Funktion muss in einer Konstantenauswertung erfolgen
constexpr Spezifizierer (C++11) spezifiziert, dass der Wert einer Variable oder Funktion zur Kompilierzeit berechnet werden kann
konstanter Ausdruck definiert einen Ausdruck , der zur Kompilierzeit ausgewertet werden kann
konstante Initialisierung setzt die Anfangswerte der static Variablen auf einen Kompilierzeit-Konstanten
Null-Initialisierung setzt den Anfangswert eines Objekts auf Null