2009-10-27 7 views
0

Je suis tout à fait certain que les tableaux de types incorporés sont unitalisés, tandis que les tableaux de UDT sont initialisés par défaut.initialisation de matrice

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 réseau est allouée sur la pile ou tas.

Cependant, je trouve qu'il est difficile de trouver une source faisant autorité sur ce sujet. Bjarne déclare que:

« Les membres des réseaux et des structures sont par défaut initialisé ou non selon que le tableau ou la structure est statique » qui ne me dit pas vraiment trop.

J'ai aussi essayé de trouver quelque chose dans la norme, mais jusqu'à présent pas en vain.

Est-ce que quelqu'un sait d'une source faisant autorité pour confirmer ce qui précède?

+2

Votre exemple avec 'foo' dépend de ce qui est' Foo' - si c'est une structure POD (par exemple 'struct Foo {int x;}'), elle ne sera pas initialisée par défaut. –

Répondre

7

ISO C++ 03 est à peu près aussi autorité qu'il obtient:

A POD-struct est une classe globale qui n'a pas d'éléments de données non statiques de type non-POD-struct, non -POD-union (ou tableau de ces types) ou référence, et n'a aucun opérateur d'affectation de copie défini par l'utilisateur et aucun destructeur défini par l'utilisateur. De même, une union POD est une union agrégée qui n'a pas de données non statiques membres de type non-POD-struct, non-POD-union (ou tableau de tels types) ou référence, et n'a pas d'opérateur d'affectation de copie défini par l'utilisateur et aucun 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 d'énumération, les types de pointeurs et les pointeurs vers les types de membres (3.9.2), ainsi que les versions cv-qualifiées de ces types (3.9.3) sont appelés collectivement types scalaires.Les types scalaires, les types POD-struct, les types d'union POD (article 9), les tableaux de ces types et les versions qualifiées cv de ces types (3.9.3) sont collectivement appelés types POD.

à zéro-initialiser un objet de type T désigne:

  • si T est un type scalaire (3,9), l'objet est fixé à la valeur de 0 (zéro) converti en T;
  • si T est un type de classe non-union, chaque membre de données non statique et chaque sous-objet de classe de base est initialisé à zéro;
  • si T est un type d'union, le premier membre de données 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.

Pour default-initialiser un objet de type T désigne:

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

Pour valeur-initialiser un objet de type T désigne:

  • si T est un type de classe (clause 9) avec un constructeur déclarée par l'utilisateur (12.1), le constructeur par défaut pour 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-union 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é en valeur;
  • si T est un type de tableau, alors chaque élément est initialisé en valeur;
  • autrement, l'objet est zéro initialisé

Chaque objet de la durée de stockage statique doit être zéro initialisées au démarrage du programme avant toute autre initialisation a lieu. [Remarque: dans certains cas, l'initialisation supplémentaire est effectuée ultérieurement.]

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

Si aucun initialiseur n'est spécifié pour un objet et que l'objet est de type classe POD (ou matrice de ceux-ci) (éventuellement qualifié de cv), l'objet doit être initialisé par défaut; Si l'objet est de type const-qualifié, le type de classe sous-jacent doit avoir un constructeur par défaut déclaré par l'utilisateur. Sinon, si aucun initialiseur 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 sont de type const-qualifié, le programme est mal formé.

Pour votre exemple, int est certainement un type POD (il est un type arithmétique), et par conséquent un local ou champ de type int, en l'absence de initialiseur, aura une valeur indéterminée.Pour Foo, cela dépend de la façon dont il est défini - en gros, s'il n'a pas de constructeur, et tous ses membres sont de type POD, alors il est lui même un type POD, et aucune initialisation n'a lieu non plus. Sinon, le constructeur par défaut est appelé. Même alors, cela ne signifie pas que membres sont initialisés - les règles sont récursives, donc les membres POD de type non-POD ne seront pas initialisés à moins que le constructeur de ce type le fasse spécifiquement (dans sa liste d'initialisation).

Les variables et les champs statiques seront dans tous les cas initialisés à zéro. Notez que cela s'applique également aux non-POD - ce qui signifie qu'une variable statique d'un type de classe a la valeur (T)0 avant même que son constructeur s'exécute.

Une astuce très pratique par défaut-initialiser tout type de POD global est d'utiliser {} dans initialiseur - notez que cela fonctionne avec struct ainsi que des tableaux:

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

« Les membres des réseaux et des structures sont par défaut initialisés ou non selon que le tableau ou la structure est statique »

Ce fait autorité, bien qu'il pourrait être plus clair:

  • Tableaux et les structures déclarées static sont initialisées en zéros.
  • des réseaux locaux et des structures de types intégrés (à savoir types qui n'ont pas des constructeurs) ne sont pas initialisés.
+0

"Les tableaux locaux et les structures ne sont pas initialisés." - Ceci est une erreur. Les variables locales (et membres!) Des types POD ne sont pas initialisées. Les variables locales et membres des types non-POD sont initialisées par défaut. –

+0

@Pavel Minaev: Je dirais "trop ​​général" plutôt que "incorrect" - bonne prise, néanmoins; mis à jour pour refléter votre commentaire. Merci! –

1

Il est dit dans la norme C++, en 8.5.9:

Si aucun initialiseur est spécifié pour un objet , et l'objet est de (peut-être cv-qualifié) classe non-POD type (ou matrice ), l'objet doit être initialisé par défaut; si l'objet est de type const-qualified, le type de classe sous-jacent doit avoir un constructeur par défaut déclaré par l'utilisateur. Sinon, si aucun initialiseur 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.