Initialization
Une déclaration d'un objet peut fournir sa valeur initiale par le processus connu sous le nom d' initialisation .
Pour chaque déclarateur , l'initialiseur, s'il n'est pas omis, peut être l'un des suivants :
=
expression
|
(1) | ||||||||
=
{
initializer-list
}
|
(2) | ||||||||
=
{
}
|
(3) | (depuis C23) | |||||||
où initializer-list est une liste non-vide, séparée par des virgules, de initializer s (avec une virgule finale optionnelle), où chaque initializer a l'une des trois formes possibles :
| expression | (1) | ||||||||
{
liste-d'initialisation
}
|
(2) | ||||||||
{
}
|
(3) | (depuis C23) | |||||||
liste-de-descripteurs
=
initialiseur
|
(4) | (depuis C99) | |||||||
|
où
designator-list
est une liste soit de désignateurs de tableau de la forme
Note : outre les initialiseurs, une initializer-list entre accolades peut apparaître dans les littéraux composés , qui sont des expressions de la forme :
|
(depuis C99) | ||||||||||||||||||||||||||||||||||||
Table des matières |
Explication
L'initialiseur spécifie la valeur initiale stockée dans un objet.
Initialisation explicite
Si un initialiseur est fourni, voir
- initialisation scalaire pour l'initialisation des types scalaires
- initialisation de tableau pour l'initialisation des types tableau
- initialisation de structure pour l'initialisation des types struct et union.
Initialisation implicite
Si aucun initialiseur n'est fourni :
- les objets avec une durée de stockage automatique sont initialisés à des valeurs indéterminées (qui peuvent être des représentations piégées )
- les objets avec une durée de stockage statique et thread-local sont initialisés à vide
Initialisation vide
|
Un objet est initialisé-vide s'il est explicitement initialisé à partir de l'initialiseur = { } . |
(depuis C23) |
Dans certains cas, un objet est initialisé vide s'il n'est pas initialisé explicitement, c'est-à-dire :
- les pointeurs sont initialisés aux valeurs de pointeur nul de leurs types
- les objets de types entiers sont initialisés à zéro non signé
- les objets de types flottants sont initialisés à zéro positif
- tous les éléments des tableaux, tous les membres des structures et les premiers membres des unions sont initialisés à vide, récursivement, et tous les bits de remplissage sont initialisés à zéro
- (sur les plateformes où les valeurs de pointeur nul et les zéros flottants ont des représentations à tous bits nuls, cette forme d'initialisation pour les statiques est normalement implémentée en les allouant dans la section .bss de l'image du programme)
Notes
Lors de l'initialisation d'un objet de durée de stockage statique ou thread-local , chaque expression dans l'initialiseur doit être une expression constante ou un littéral de chaîne .
Les initialiseurs ne peuvent pas être utilisés dans les déclarations d'objets de type incomplet, des tableaux de taille variable (VLA), et des objets de portée de bloc avec liaison.
Les valeurs initiales des paramètres de fonction sont établies comme si elles étaient assignées à partir des arguments d'un appel de fonction , plutôt que par initialisation.
Si une valeur indéterminée est utilisée comme argument à un appel de bibliothèque standard, le comportement est indéfini. Sinon, le résultat de toute expression impliquant des valeurs indéterminées est une valeur indéterminée (par exemple int n ; , n peut ne pas être égale à elle-même et peut sembler changer de valeur lors de lectures ultérieures)
|
Il n'existe pas de construction spéciale en C correspondant à l'initialisation par valeur en C++ ; cependant, = { 0 } (ou ( T ) { 0 } dans les littéraux composés) (depuis C99) peut être utilisé à la place, car la norme C n'autorise pas les structures vides, les unions vides ou les tableaux de longueur nulle. |
(jusqu'à C23) |
|
L'initialiseur vide = { } (ou ( T ) { } dans les littéraux composés) peut être utilisé pour obtenir la même sémantique que l'initialisation par valeur en C++. |
(depuis C23) |
Exemple
#include <stdlib.h> int a[2]; // initialise a à {0, 0} int main(void) { int i; // initialise i à une valeur indéterminée static int j; // initialise j à 0 int k = 1; // initialise k à 1 // initialise int x[3] à 1,3,5 // initialise int* p à &x[0] int x[] = { 1, 3, 5 }, *p = x; // initialise w (un tableau de deux structs) à // { { {1,0,0}, 0}, { {2,0,0}, 0} } struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2}; // une expression d'appel de fonction peut être utilisée pour une variable locale char* ptr = malloc(10); free(ptr); // Erreur : les objets avec durée de stockage statique nécessitent des initialiseurs constants // static char* ptr = malloc(10); // Erreur : VLA ne peut pas être initialisé // int vla[n] = {0}; }
Références
- Norme C17 (ISO/CEI 9899:2018) :
-
- 6.7.9 Initialisation (p: 100-105)
- Norme C11 (ISO/IEC 9899:2011) :
-
- 6.7.9 Initialisation (p: 139-144)
- Norme C99 (ISO/IEC 9899:1999) :
-
- 6.7.8 Initialisation (p: 125-130)
- Norme C89/C90 (ISO/IEC 9899:1990) :
-
- 6.5.7 Initialisation
Voir aussi
|
Documentation C++
pour
Initialization
|