web-dev-qa-db-fra.com

Initialisation zéro C ++

J'ai du mal à comprendre quand et pourquoi exactement un membre de ma classe est initialisé à zéro selon http://en.cppreference.com/w/cpp/language/zero_initialization .

Considérez le programme de test suivant:

#include <iostream>
#include <stdio.h>

class MyTest {
private:
    const static unsigned int dimension = 8;
    void (* myFunctions [dimension])();

public: 
    MyTest() {}

    void print() { 
        for(unsigned int i=0; i < MyTest::dimension; i++) {
            printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);
        }   
    }
};


int main() {
    //We declare and initialize an object on the stack 
    MyTest testObj = {};
    testObj.print();

    return 0;
}

Je déclare une classe pour avoir un tableau de 8 pointeurs de fonction de la signature "void functionname ()". Lorsque je déclare et initialise un objet de la classe dans main comme MyTest testObj = {}; ou MyTest testObj;, Je m'attendais à ce qu'il soit initialisé à zéro, c'est-à-dire que tous les pointeurs sont des pointeurs nuls.

Cependant, la compilation avec g ++ 5.3.0 sur ma machine Windows 10 avec g++ -m32 -o test -std=c++14 test.cpp && test machine donne la sortie:

myFunctions[0] = 76dd6b7d
myFunctions[1] = 00401950
myFunctions[2] = 0061ff94
myFunctions[3] = 004019ab
myFunctions[4] = 00401950
myFunctions[5] = 00000000
myFunctions[6] = 003cf000
myFunctions[7] = 00400080

Qui ressemblent à des valeurs non initialisées de la pile.

Si je déplace la déclaration de l'objet en dehors de main (en tant que variable globale), il affiche à nouveau tous les zéros.

Si j'ai bien compris la référence cpp, c'est parce que j'ai une variable avec une durée de stockage statique, et qu'elle est donc initialisée à zéro. Il initialise mon type de classe en initialisant à zéro tous les membres de données non statiques de ma classe (c'est-à-dire le tableau myFunctions). Un tableau est initialisé en initialisant zéro chaque élément de celui-ci, qui, dans mon cas de pointeur de fonction, est un pointeur nul.

Pourquoi ne initialise-t-il pas à zéro mon objet la pile quand je le déclare avec MyTest testObj = {};?

21
Maximilian Gerhardt

Le suivant

MyTest testObj = {};

n'est pas pas initialisation zéro pour MyTest, mais appelle simplement son constructeur par défaut. La page cppreference explique pourquoi (c'est moi qui souligne):

Dans le cadre de la séquence d'initialisation de valeur pour les types non-classe et pour les membres de types de classe initialisés par valeur qui n'ont pas de constructeurs , y compris l'initialisation de valeur des éléments de agrégats pour lesquels aucun initialiseur n'est fourni.

MyTest est un type de classe et a un constructeur.


Définition du constructeur avec

MyTest() = default;

va à la place zéro initialiser l'objet.

Citations standard pertinentes (je souligne) ci-dessous.

De [dcl.init # 6] :

Pour initialiser en valeur un objet de type T, cela signifie:

  • si T est un type de classe (éventuellement qualifié par cv) sans constructeur par défaut ([class.ctor]) ou un constructeur par défaut fourni par l'utilisateur ou supprimé, alors l'objet est initialisé par défaut;

  • si T est un type de classe (éventuellement qualifié par cv) sans constructeur par défaut fourni par l'utilisateur ou supprimé, alors l'objet est initialisé à zéro et les contraintes sémantiques pour l'initialisation par défaut sont vérifiées, et si T a un constructeur par défaut non trivial, l'objet est initialisé par défaut;

  • ...

De [dcl.init.list] :

L'initialisation de liste d'un objet ou d'une référence de type T est définie comme suit:

  • ...

  • Sinon, si la liste d'initialisation n'a pas d'éléments et T est un type de classe avec un constructeur par défaut, l'objet est initialisé en valeur.

30
Vittorio Romeo