Zero-initialization
Définit la valeur initiale d'un objet à zéro.
Table des matières |
Syntaxe
Notez que ceci n'est pas la syntaxe pour l'initialisation à zéro, qui ne possède pas de syntaxe dédiée dans le langage. Ce sont des exemples d'autres types d'initialisations, qui peuvent effectuer une initialisation à zéro.
static
T
object
;
|
(1) | ||||||||
T
()
;
T
t
T
|
(2) | ||||||||
CharT
array
[
n
]
=
"
short-sequence
";
|
(3) | ||||||||
Explication
L'initialisation à zéro est effectuée dans les situations suivantes :
Les effets de l'initialisation à zéro sont :
-
Si
Test un type scalaire , l'objet est initialisé à la valeur obtenue en convertissant explicitement le littéral entier 0 (zéro) enT. -
Si
Test un type classe non-union :
-
- tous les bits de remplissage sont initialisés à zéro,
- chaque membre de données non statique est initialisé à zéro,
- chaque classe de base non virtuelle sous-objet est initialisée à zéro, et
- si l'objet n'est pas un sous-objet de classe de base, chaque classe de base virtuelle sous-objet est initialisée à zéro.
-
Si
Test un type union :
-
- tous les bits de remplissage sont initialisés à des bits zéro, et
- le premier membre de données nommé non statique de l'objet est initialisé à zéro.
-
Si
Test un type tableau, chaque élément est initialisé à zéro. -
Si
Test un type référence, rien n'est fait.
Notes
Comme décrit dans l'initialisation non-locale , les variables statiques et thread-local (depuis C++11) qui ne sont pas constant-initialisées sont zero-initialized avant toute autre initialisation. Si la définition d'une variable non-classe non-locale n'a pas d'initialiseur, alors l'initialisation par défaut ne fait rien, laissant le résultat de la zero-initialization antérieure inchangé.
Un pointeur initialisé à zéro est la valeur du pointeur nul de son type, même si la valeur du pointeur nul n'est pas zéro intégral.
Exemple
#include <iostream> #include <string> struct A { int a, b, c; }; double f[3]; // initialisés à zéro vers trois 0.0 int* p; // initialisé à zéro vers la valeur de pointeur nul // (même si la valeur n'est pas l'entier 0) std::string s; // initialisé à zéro vers une valeur indéterminée, puis // initialisé par défaut vers "" par le constructeur par défaut de std::string int main(int argc, char*[]) { delete p; // sûr de supprimer un pointeur nul static int n = argc; // initialisé à zéro vers 0 puis initialisé par copie vers argc std::cout << "n = " << n << '\n'; A a = A(); // l'effet est identique à : A a{}; ou A a = {}; std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n"; }
Sortie possible :
n = 1
a = {0 0 0}
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 correct |
|---|---|---|---|
| CWG 277 | C++98 |
les pointeurs pouvaient être initialisés avec une expression
non constante de valeur 0, qui n'est pas une constante de pointeur nul |
doit être initialisé avec une expression constante
intégrale de valeur 0 |
| CWG 694 | C++98 | l'initialisation à zéro pour les types classe ignorait le remplissage | le remplissage est initialisé avec des bits à zéro |
| CWG 903 | C++98 |
l'initialisation à zéro pour les types scalaires définissait la valeur initiale à la valeur
convertie d'une expression constante intégrale avec valeur 0 |
l'objet est initialisé à la valeur
convertie du littéral entier 0 |
| CWG 2026 | C++98 |
l'initialisation à zéro était spécifiée pour toujours
se produire en premier, même avant l'initialisation constante |
pas d'initialisation à zéro si
l'initialisation constante s'applique |
| CWG 2196 | C++98 | l'initialisation à zéro pour les types classe ignorait les sous-objets de classe de base | ils sont également initialisés à zéro |
| CWG 2253 | C++98 |
il n'était pas clair si l'initialisation à zéro
s'appliquait aux champs de bits sans nom |
elle s'applique (tous les bits de remplissage
sont initialisés avec des bits à zéro) |