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
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. –