constinit
specifier
(since C++20)
-
-
constinit- affirme qu'une variable a une initialisation statique, c'est-à-dire zero initialization et constant initialization , sinon le programme est mal formé.
-
Table des matières |
Explication
Le spécificateur constinit déclare une variable avec une durée de stockage statique ou thread.
|
Le spécificateur constinit peut également être appliqué aux déclarations de liaisons structurées . Dans ce cas, constinit est également appliqué à la variable à nom unique introduite par la déclaration. |
(depuis C++26) |
Si une variable est déclarée avec constinit , sa déclaration d'initialisation doit être appliquée avec constinit . Si une variable déclarée avec constinit a une initialisation dynamique (même si elle est exécutée comme initialisation statique ), le programme est mal formé.
Si aucune déclaration constinit n'est accessible au point de la déclaration d'initialisation, le programme est mal formé, aucun diagnostic requis.
constinit ne peut pas être utilisé conjointement avec constexpr . Lorsque la variable déclarée est une référence, constinit est équivalent à constexpr . Lorsque la variable déclarée est un objet, constexpr impose que l'objet doit avoir une initialisation statique et une destruction constante et rend l'objet qualifié const, cependant, constinit n'impose pas la destruction constante ni la qualification const. Par conséquent, un objet d'un type qui possède des constructeurs constexpr mais pas de destructeur constexpr (par exemple std:: shared_ptr < T > ) peut être déclaré avec constinit mais pas avec 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); // erreur
constinit peut également être utilisé dans une déclaration non initialisante pour indiquer au compilateur qu'une variable thread_local est déjà initialisée, réduisant la surcharge qui serait autrement engendrée par une variable de garde cachée.
extern thread_local constinit int x; int f() { return x; } // aucune vérification d'une variable de garde nécessaire
Notes
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_constinit
|
201907L
|
(C++20) | constinit |
Mots-clés
Exemple
#include <cassert> constexpr int square(int i) { return i * i; } int twice(int i) { return i + i; } constinit int sq = square(2); // OK : l'initialisation est effectuée à la compilation // constinit int x_x = twice(2); // Erreur : initialiseur à la compilation requis int square_4_gen() { static constinit int pow = square(4); // constinit int prev = pow; // Erreur : constinit ne peut être appliqué qu'à une // variable avec durée de stockage statique ou thread int prev = pow; pow = pow * pow; return prev; } int main() { assert(sq == 4); sq = twice(1); // Contrairement à constexpr cette valeur peut être modifiée ultérieurement à l'exécution assert(sq == 2); assert(square_4_gen() == 16); assert(square_4_gen() == 256); assert(square_4_gen() == 65536); }
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement correct |
|---|---|---|---|
| CWG 2543 | C++20 |
le comportement n'était pas clair si la variable déclarée avec
constinit
est initialisée dynamiquement dans le cadre de l'initialisation statique |
le programme est mal-
formé dans ce cas |
Voir aussi
consteval
spécificateur
(C++20)
|
spécifie qu'une fonction est une fonction immédiate , c'est-à-dire que tout appel à la fonction doit être dans une évaluation constante |
constexpr
spécificateur
(C++11)
|
spécifie que la valeur d'une variable ou d'une fonction peut être calculée à la compilation |
| expression constante | définit une expression qui peut être évaluée à la compilation |
| initialisation constante | définit les valeurs initiales des variables statiques comme une constante à la compilation |
| initialisation à zéro | définit la valeur initiale d'un objet à zéro |