Que signifient les expressions suivantes en C ++: initialisation zéro, par défaut et valeur?

Que signifient les phrases suivantes en C ++:

Que devrait savoir un développeur C ++ à leur sujet?

Une chose à réaliser est que «l’initialisation de la valeur» est nouvelle avec la norme C ++ 2003 – elle n’existe pas dans la norme originale de 1998 (je pense que cela pourrait être la seule différence qui soit plus qu’une clarification). Voir la réponse de Kirill V. Lyadvinsky pour les définitions directement issues de la norme.

Voir cette réponse précédente sur le comportement de l’ operator new pour plus de détails sur les différents comportements de ce type d’initialisation et quand ils entrent en jeu (et quand ils diffèrent de c ++ 98 à C ++ 03):

  • Les parenthèses après le nom du type font-elles une différence avec new?

Le point principal de la réponse est:

Parfois, la mémoire renvoyée par le nouvel opérateur sera initialisée, et parfois elle ne le sera pas selon que le type que vous modifiez est un POD ou une classe contenant des membres POD et utilisant un constructeur par défaut généré par le compilateur. .

  • En C ++ 1998, il existe 2 types d’initialisation: zéro et par défaut
  • En C ++ 2003, un troisième type d’initialisation, l’initialisation de la valeur a été ajoutée.

Pour dire le moins, c’est plutôt complexe et lorsque les différentes méthodes sont subtiles.

Une chose à prendre en compte est que MSVC suit les règles C ++ 98, même dans VS 2008 (VC 9 ou cl.exe version 15.x).

L’extrait suivant montre que MSVC et Digital Mars suivent les règles C ++ 98, tandis que GCC 3.4.5 et Comeau suivent les règles C ++ 03:

 #include  #include  #include  struct A { int m; }; // POD struct B { ~B(); int m; }; // non-POD, comstackr generated default ctor struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m int main() { char buf[sizeof(B)]; memset( buf, 0x5a, sizeof( buf)); // use placement new on the memset'ed buffer to make sure // if we see a zero result it's due to an explicit // value initialization B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized //C++03 rules - pB->m is set to 0 printf( "m is %d\n", pB->m); return 0; } 

C ++ 03 Standard 8.5 / 5:

Initialiser à zéro un object de type T signifie:
– si T est un type scalaire (3.9), l’object est mis à 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 sous-object de classe de base est initialisé à zéro;
– si T est un type d’union, le premier membre de données nommé de l’object est initialisé à zéro;
– si T est un type 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 object 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 tableau, chaque élément est initialisé par défaut;
– sinon, l’object est initialisé à zéro.

Valoriser-initialiser un object de type T 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, chaque membre de données et composant de classe de base non statique de T est initialisé en valeur;
– si T est un type tableau, alors chaque élément est initialisé en valeur;
– sinon, l’object est initialisé à zéro

Un programme qui appelle une initialisation par défaut ou une initialisation de valeur d’une entité de type référence est mal formé. Si T est un type qualifié cv, la version non qualifiée cv de T est utilisée pour ces définitions d’initialisation à zéro, d’initialisation par défaut et d’initialisation de valeur.