78 votes

C et C ++: Initialisation partielle de la structure automatique

Par exemple, si somestruct a trois entier les membres, j'avais toujours pensé que c'était OK pour le faire en C (ou C++) fonction:

somestruct s = {123,};

Le premier membre sera initialisé à 123 et les deux derniers serait initialisé à 0. Je fais souvent la même chose avec automatique de tableaux, de l'écriture int arr[100] = {0,}; , de sorte que tous les entiers dans un tableau sont initialisés à zéro.


Récemment, j'ai lu dans le GNU C Manuel de Référence :

Si vous n'avez pas initialiser une variable de structure, l'effet dépend de si c'est le stockage statique (voir Classe de Stockage des Prescripteurs) ou pas. Si elle l'est, membres avec les types intégraux sont initialisés à 0 et pointeur membres sont initialisées à NULL; sinon, la valeur de la la structure des membres est de durée indéterminée.


Quelqu'un peut-il me dire en quoi le C et le C++ normes de dire concernant partielle automatique de la structure et automatique de l'initialisation de tableau? Je fais le code ci-dessus dans Visual Studio sans problème, mais je veux être compatible avec gcc/g++, et peut-être d'autres compilateurs. Merci

109voto

Alok Save Points 115848

Liés gcc documentation ne parle pas de la Partielle de l'Initialisation , il parle juste de (Complète)de l'Initialisation ou de ne Pas faire d'Initialisation.

Qu'est-ce que partielle de l'Initialisation?

Les normes ne définissent pas Partielle de l'initialisation des objets, soit il est de Terminer l'initialisation ou de la Non-initialisation. Partielle d'Initialisation est un non-standard de la terminologie qui désigne communément une situation où vous fournir des initialiseurs mais pas tous je.e: de moins en Moins les initialiseurs que la taille du tableau ou le nombre d'éléments de structure en cours d'initialisation.

Exemple:

int array[10] = {1,2};                    //Case 1:Partial Initialization

Qu'est-ce que (Complète)de l'Initialisation ou de ne Pas faire d'Initialisation?

Initialisation des moyens fournissant une certaine valeur initiale de la variable en cours de création au moment même où il est en cours de création. c'est à dire: le même code de déclaration.

Exemple:

int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initialization
int array[10];                            //Case 3:No Initialization

La cité le paragraphe décrit le comportement d' Case 3.

Les règles concernant l'Initialisation Partielle(Case 1) sont bien définies par les normes et ces règles ne dépendent pas du type de stockage de la variable en cours d'initialisation.
Autant que je sache, Tous les compilateurs ont 100% de conformité à ces règles.


Quelqu'un peut-il me dire en quoi le C et le C++ normes de dire concernant partielle automatique de la structure et automatique de l'initialisation de tableau?

Le C et le C++ normes garantissent que même si un tableau d'entiers est situé sur le stockage automatique et si il y a moins d'initialiseurs dans un corset-ci-joint la liste puis le non initialisée éléments doit être initialisé à l' 0.

Standard C99 6.7.8.21

Si il y a moins d'initialiseurs dans un corset-ci-joint la liste qu'il y a des éléments ou des membres d'un agrégat, ou moins de caractères dans une chaîne littérale utilisée pour initialiser un tableau de taille connue qu'il y a d'éléments dans le tableau, le reste de la somme doit être initialisé implicitement le même que les objets qui ont statique de la durée de stockage.


En C++, les règles sont établies avec un peu de différence.

C++03 Standard 8.5.1 Agrégats
Paragraphe 7:

Si il y a moins d'initialiseurs dans la liste qu'il y a de membres dans l'ensemble, chaque membre n'est pas explicitement initialisée est la valeur initialisée (8.5). [Exemple:

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

initialise ss.a avec 1, ss.b avec "asdf", et ss.c de la valeur d'une expression de la forme int(), qui est,0. ]

Alors que la Valeur d'Initialisation est défini dans la
C++03 8.5 Initialiseurs
Paragraphe 5:

À la valeur d'initialiser un objet de type T signifie:
- si T est un type de classe (clause 9) avec un utilisateur déclaré par le constructeur (12.1), puis le constructeur par défaut pour T est appelé (et l'initialisation est mal formé, si T n'a pas de accessible le constructeur par défaut);
- si T est une non-union type de classe sans un utilisateur déclaré par le constructeur, puis tous les non-statique membre des données et de la classe de base de la composante de T est la valeur initialisée;
- si T est de type tableau, chaque élément est la valeur initialisée;
- sinon, l'objet est initialisé à zéro

18voto

caf Points 114951

En C, les objets sont jamais partiellement initialisé - si une partie d'entre eux est initialisé, l'ensemble de l'objet (et tous les sous-objets de manière récursive) sont initialisées. Si aucun explicite initialiser est fourni les éléments sont initialisés à zéro du type approprié".

La citation à votre question se réfère lorsque l'initialiser pour l'ensemble de l'objet est complètement laissé de côté, pas quand un sous-objet n'a pas une initialiser. Par exemple, en supposant que l' arr a automatique de la durée de stockage, puis ceci:

int arr[100] = { 123 };

initialise arr[0] de 123 et tous les autres éléments de l' arr de 0. Considérant que la présente:

int arr[100];

les feuilles de chaque élément de l' arr non initialisée. C'est ce dernier cas que la citation est une référence.

5voto

rocket441 Points 101

Les dernières versions de gcc permettent également d’initialiser "partiellement" et zeromem en même temps:

 typedef struct{
  int a,b,c;
}T;

T s = {0, .b=5};
 

les membres de la structure auront maintenant ces valeurs: a=0, b=5, c=0

je n'ai aucune information sur si d'autres compilateurs le permettent ou non: p

0voto

RolandXu Points 1455

Si la variable est globale et statique, elle alloue dans la zone globale des fichiers binaires initialisée à zéro. Si la variable est locale, elle est allouée dans la pile, le compilateur n'initialise pas la mémoire dans la pile (certaines versions de débogage peuvent s'initialiser, mais la version finale ne le fait jamais).

Si la variable est allouée dans Heap, le compilateur ne l'initialise pas non plus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X