Question

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

int foo [5]; // contiendra des ordures

Foo Foo [5]; // contiendra 5 objets Foo initialisés par défaut

Cela se produit que le tableau soit alloué sur la pile ou sur le tas.

Cependant, j'ai du mal à trouver une source faisant autorité à ce sujet. Bjarne déclare que:

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

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

Quelqu'un at-il connaissance d'une source faisant autorité pour confirmer ce qui précède?

Était-ce utile?

La solution

ISO C ++ 03 fait autant autorité que possible:

  

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

     

Initialiser à zéro un objet de type T signifie:

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

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 type de tableau, chaque élément est initialisé par défaut;
  •   
  • sinon, l'objet est initialisé à zéro.
  •   
     

Initialiser un objet de type T par valeur signifie:

     
      
  • si T est un type de classe (clause 9) avec un constructeur déclaré par l'utilisateur (12.1), 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-union sans constructeur déclaré par l'utilisateur, tous les membres de données non statiques et les composants de classe de base de T sont initialisés par valeur;
  •   
  • si T est un type de tableau, chaque élément est initialisé par 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. [Remarque: dans certains cas, l'initialisation supplémentaire est effectuée ultérieurement.]

     

Un objet dont l'initialiseur est un ensemble vide de parenthèses, à savoir, (), doit être initialisé avec une valeur.

     

Si aucun initialiseur n'est spécifié pour un objet et que celui-ci est de type classe POD (éventuellement qualifié par cv) (ou son tableau), l'objet doit être initialisé par défaut; si l'objet est de type qualifié const, 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 qualifié, le programme est mal formé.

Par exemple, int est définitivement un type de POD (de type arithmétique), et par conséquent un champ ou champ de type int , en l'absence d'initialiseur, aura une valeur indéterminée. Pour Foo , cela dépend de la façon dont il est défini - grosso modo, s'il n'a pas de constructeur et que tous ses membres sont de types POD, il s'agit alors d'un type POD, et aucune initialisation. a lieu non plus. Sinon, le constructeur par défaut est appelé. Même dans ce cas, cela ne signifie pas que les membres sont initialisés - les règles sont récursives. Par conséquent, les membres POD de type non-POD ne seront initialisés que si le constructeur de ce type le fait spécifiquement (dans son initializer liste).

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

Une astuce pratique pour initialiser par défaut tout type de POD agrégé consiste à utiliser {} dans l'initialiseur - notez qu'il fonctionne avec des structures ainsi que des tableaux:

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

Autres conseils

On dit dans le standard C ++, dans 8.5.9:

  

Si aucun initialiseur n'est spécifié pour un   objet, et l'objet est de (éventuellement   cv-qualifié) type de classe non-POD (ou   son tableau), l'objet doit être   initialisé par défaut; si l'objet est   de type qualifié const, le   type de classe sous-jacente 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, le   objet et ses sous-objets, le cas échéant,   avoir une valeur initiale indéterminée.

  

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

Cela fait autorité, même si cela pourrait être plus clair:

  • Les tableaux et les structures déclarés comme static sont initialisés à zéro.
  • Les tableaux et les structures locaux des types intégrés (les types c'est-à-dire qui n'ont pas de constructeur) ne sont pas initialisés.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top