0 votes

initialisation du tableau

Je suis certain que les tableaux de types intégrés sont unitialisés, alors que les tableaux de UDT sont initialisés par défaut.

int foo[5]; // will contain junk Foo foo[5]; // will contain 5 Foo objects that are default initialized

Cela se produit indépendamment du fait que le tableau soit alloué sur la pile ou sur le tas.

Cependant, j'ai du mal à trouver une source faisant autorité en la matière. Bjarne affirme que :

"Les membres des tableaux et des structures sont initialisés par défaut ou non selon que le tableau ou la structure est statique ou non", ce qui ne me dit pas grand-chose.

J'ai également essayé de trouver quelque chose dans la norme, mais sans succès jusqu'à présent.

Quelqu'un connaît-il une source faisant autorité pour confirmer ce qui précède ?

6voto

Pavel Minaev Points 60647

La norme ISO C++03 fait autorité en la matière :

Une structure POD est une classe agrégée qui n'a pas de membres de données non statiques de type structure non POD, union non POD (ou tableau de ces types) ou référence, et qui n'a pas d'opérateur d'affectation de copie défini par l'utilisateur ni de destructeur défini par l'utilisateur. De même, une union POD est une union agrégée qui n'a pas de membres de données non statiques de type non-POD-struct, non-POD-union (ou tableau de tels types) ou référence, et qui n'a pas d'opérateur d'affectation de copie défini par l'utilisateur ni de destructeur défini par l'utilisateur. Une classe POD est une classe qui est soit une structure POD, soit une union POD.

Les types arithmétiques (3.9.1), les types énumération, les types pointeur et les types pointeur sur membre (3.9.2), ainsi que les versions qualifiées cv de ces types (3.9.3) sont collectivement appelés types scalaires. Les types scalaires, les types POD-struct, les types POD-union (clause 9), les tableaux de ces types et les versions qualifiées cv de ces types (3.9.3) sont collectivement appelés types POD.

L'initialisation à zéro d'un objet de type T signifie :

  • si T est un type scalaire (3.9), l'objet est mis à la valeur 0 (zéro) convertie en T ;
  • si T est un type de classe non syndiqué, chaque membre de données non statique et chaque sous-objet de la classe de base est zéro initialisation est initialisé à zéro ;
  • si T est un type union, le premier membre nommé de l'objet est initialisé à zéro ;
  • si T est un type de tableau, chaque élément est initialisé à zéro ;
  • si T est un type de référence, aucune initialisation n'est effectuée.

Initialiser par défaut un objet de type T signifie :

  • si T est un type de classe non POD (clause 9), le constructeur par défaut de T est appelé (et l'initialisation est mal formée si T n'a pas de constructeur par défaut accessible) ;
  • si T est un tableau, chaque élément est initialisé par défaut ;
  • sinon, l'objet est initialisé à zéro.

Initialiser un objet de type T par une valeur signifie :

  • si T est un type de classe (clause 9) avec un constructeur déclaré par l'utilisateur (12.1), alors le constructeur par défaut de T est appelé (et l'initialisation est mal formée si T n'a pas de constructeur par défaut accessible) ;
  • si T est un type de classe non syndiqué sans constructeur déclaré par l'utilisateur, alors chaque membre de données non statique et chaque composant de classe de base de T est initialisé par une valeur ;
  • si T est un type de tableau, chaque élément est initialisé par une valeur ;
  • sinon, l'objet est initialisé à zéro

Chaque objet de durée de stockage statique doit être initialisé à zéro au démarrage du programme avant toute autre initialisation. [Note : dans certains cas, une initialisation supplémentaire est effectuée ultérieurement].

Un objet dont l'initialisateur est un ensemble vide de parenthèses, c'est-à-dire (), doit être initialisé par une valeur.

Si aucun initialisateur n'est spécifié pour un objet, et que l'objet est d'un type de classe (ou d'un tableau de ce type) non POD (éventuellement qualifié cv), l'objet est initialisé par défaut ; si l'objet est d'un type qualifié const, le type de classe sous-jacent doit avoir un constructeur par défaut déclaré par l'utilisateur. Dans le cas contraire, si aucun initialisateur n'est spécifié pour un objet non statique, l'objet et ses sous-objets, le cas échéant, ont une valeur initiale indéterminée ; si l'objet ou l'un de ses sous-objets est de type const-qualifié, le programme est mal formé.

Pour votre exemple, int est bien un type POD (c'est un type arithmétique), et donc un local ou un champ de type int en l'absence d'initialisateur, aura une valeur indéterminée. Pour les Foo En gros, s'il n'a pas de constructeur et que tous ses membres sont des types POD, il est lui-même un type POD et aucune initialisation n'a lieu. Dans le cas contraire, le constructeur par défaut est appelé. Même dans ce cas, cela ne signifie pas que membres sont initialisés - les règles sont récursives, de sorte que les membres POD d'un type non POD ne seront pas initialisés à moins que le constructeur de ce type ne le fasse spécifiquement (dans sa liste d'initialisateurs).

Les variables et champs statiques seront dans tous les cas initialisés à zéro. Notez que ceci s'applique également aux non-PODs - ce qui signifie qu'une variable statique d'un type de classe est garantie d'avoir tous les champs définis récursivement à (T)0 avant même l'exécution de son constructeur.

Une astuce pratique pour initialiser par défaut n'importe quel type de POD agrégé est d'utiliser {} dans l'initialisateur - notez que cela fonctionne aussi bien avec les structures qu'avec les tableaux :

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

1voto

Adam Liss Points 27815

"Les membres des tableaux et des structures sont initialisés par défaut ou non selon que le tableau ou la structure est statique ou non.

Ce texte fait autorité, même s'il pourrait être plus clair :

  • Les tableaux et les structures déclarés comme static sont initialisés à zéro.
  • Les tableaux locaux et les structures de types intégrés ( c'est-à-dire qui n'ont pas de constructeurs) ne sont pas initialisés.

1voto

Charles Salvia Points 28661

C'est ce que dit la norme C++, au point 8.5.9 :

Si aucun initialisateur n'est spécifié pour un objet et que l'objet est de type (éventuellement cv-qualifié) qui n'est pas de type classe POD (ou de type ou un de ses tableaux), l'objet est initialisé par défaut ; si l'objet est de type de type qualifié const, l'initialisateur u déclaré par l'utilisateur. Sinon, si aucun initialisateur n'est n'est spécifié pour un objet non statique, l'objet [ ] ont une valeur initiale indéterminée.

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