Namespaces
Variants

Constant initialization

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

Définit les valeurs initiales des variables static à une constante évaluée à la compilation.

Table des matières

Explication

Initialisation constante est effectuée dans les cas suivants :

  • Initialiser un objet de POD type avec static storage duration avec une constant expression.
(jusqu'à C++11)
  • Initialiser une référence avec static ou thread storage duration, où toutes les conditions suivantes sont satisfaites :
  • un lvalue désignant un objet avec static storage duration
  • un objet temporaire
  • un subobject d'un objet temporaire
  • une fonction
  • Initialiser un objet avec static ou thread storage duration, et l'une des conditions suivantes est satisfaite :
  • Si l'objet est initialisé par un appel de constructeur, où la full-expression d'initialisation est une constant expression, sauf qu'elle peut aussi invoquer des constexpr constructors pour l'objet et ses subobjects (même si ces objets sont de types classe non- literal ).
  • Sinon, soit l'objet est value-initialized soit chaque full-expression qui apparaît dans son initialiseur est une constant expression.
(depuis C++11)
(jusqu'à C++17)
(depuis C++17)
(jusqu'à C++20)
(depuis C++20)

Les effets de l'initialisation constante sont les mêmes que ceux de l'initialisation correspondante, sauf qu'il est garanti qu'elle est terminée avant toute autre initialisation d'un objet statique ou thread-local (since C++11) commence.

Notes

Le compilateur est autorisé à initialiser d'autres objets statiques et thread-locaux (depuis C++11) en utilisant l'initialisation constante, s'il peut garantir que la valeur serait la même que si l'ordre standard d'initialisation était suivi.

L'initialisation constante se produit généralement lorsque le programme se charge en mémoire, dans le cadre de l'initialisation de l'environnement d'exécution du programme.

Exemple

#include <iostream>
#include <array>
struct S
{
    static const int c;
};
const int d = 10 * S::c; // pas une expression constante : S::c n'a pas d'initialiseur
                         // précédent, cette initialisation se produit après const
const int S::c = 5;      // initialisation constante, garantie de se produire en premier
int main()
{
    std::cout << "d = " << d << '\n';
    std::array<int, S::c> a1; // OK : S::c est une expression constante
//  std::array<int, d> a2;    // erreur : d n'est pas une expression constante
}

Sortie :

d = 50

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 tel que publié Comportement corrigé
CWG 441 C++98 les références ne pouvaient pas être initialisées de manière constante rendues initialisables de manière constante
CWG 1489 C++11 il n'était pas clair si l'initialisation par valeur
d'un objet pouvait être une initialisation constante
c'est possible
CWG 1747 C++11 la liaison d'une référence à une fonction ne pouvait pas être une initialisation constante c'est possible
CWG 1834 C++11 la liaison d'une référence à une xvalue ne pouvait pas être une initialisation constante c'est possible

Voir aussi