Ils ne sont pas nuls si vous n'initialisez pas la structure.
Snapshot s;// receives no initializationSnapshot s ={};// value initializes all members
Le second mettra tous les membres à zéro, le premier les laisse à des valeurs non spécifiées. Notez qu'il est récursif:
structParent{Snapshot s;};Parent p;// receives no initializationParent p ={};// value initializes all members
Le second fera p.s.{x,y}zéro. Vous ne pouvez pas utiliser ces listes d'initialisation agrégées si vous avez des constructeurs dans votre structure. Si tel est le cas, vous devrez ajouter une bonne initialisation à ces constructeurs
structSnapshot{int x;double y;Snapshot():x(0),y(0){}// other ctors / functions...};
Initialise à la fois x et y à 0. Notez que vous pouvez utiliser x(), y()pour les initialiser sans tenir compte de leur type: c'est alors l'initialisation de la valeur, et donne généralement une valeur initiale correcte (0 pour int, 0,0 pour double, appelant le constructeur par défaut pour défini par l'utilisateur types qui ont des constructeurs déclarés par l'utilisateur, ...). Ceci est important surtout si votre structure est un modèle.
Cela produit de nombreux avertissements dans mon compilateur.
River-Claire Williamson
1
Roger: Essayez d'utiliser la structure nommée dans l'initialiseur, c'est ce que je fais et je ne reçois aucun avertissement dans VC 2012: Snapshot s = Snapshot ();
Kit10
@Johannes Schaub - litb Fonctionnera-t-il Snapshot s = {};pour les non-membres du POD (pour les mettre à zéro)?
ontherocks
2
C ++ 11 vous permet maintenant de les initialiser dans la définition de la structure ou de la classe, comme ceci: struct Snapshot {double x {0}; // avec accolades int y = 0; // ou juste du style old school 'par affectation' qui est aussi vraiment l'initialisation};
ikku100
1
Est-ce que "Snapshot s = {};" fait partie de la norme?
Stefan
41
Non, ils ne sont pas 0 par défaut. Le moyen le plus simple de s'assurer que toutes les valeurs ou par défaut à 0 est de définir un constructeur
Snapshot(): x(0), y(0){}
Cela garantit que toutes les utilisations de Snapshot auront des valeurs initialisées.
L'inconvénient est que la structure n'est plus un type POD, car elle a un constructeur. Cela interrompra certaines opérations telles que l'écriture dans un fichier temporaire.
finnw
16
@finnw: C ++ 11 corrige cela, bien que la structure ne soit pas POD, c'est une "disposition standard".
Ben Voigt
20
En général, non. Cependant, une structure déclarée comme portée de fichier ou statique dans une fonction / sera / sera initialisée à 0 (comme toutes les autres variables de ces étendues):
int x;// 0int y =42;// 42struct{int a, b;} foo;// 0, 0void foo(){struct{int a, b;} bar;// undefinedstaticstruct{int c, d;} quux;// 0, 0}
Ce n'est vraiment pas une hypothèse sûre. vous ne devez pas vous fier à la valeur de tout ce que vous n'avez pas initialisé
Hasturkun
24
Les objets de durée de stockage statique sont toujours initialisés à zéro - voir stackoverflow.com/questions/60653/… pour une citation de la norme. Que ce soit du bon style est une autre affaire.
bdonlan
12
Avec POD, vous pouvez également écrire
Snapshot s ={};
Vous ne devez pas utiliser memset en C ++, memset a l'inconvénient que s'il y a un non-POD dans la structure, il le détruira.
ou comme ça:
struct init{template<typename T>operator T *(){returnnew T();}};Snapshot* s = init();
@Andy Most Vexing Parse transforme des choses qui ressemblent à des cteurs normaux - SomeType foo();c'est le cas typique, bien que cela puisse arriver avec d'autres - en définitions de fonctions (dans ce cas, une fonction fooqui revient SomeType). Désolé pour la nécro, mais si quelqu'un d'autre tombe dessus, j'ai pensé que je répondrais.
Fund Monica's Lawsuit
8
En C ++, utilisez des constructeurs sans argument. En C, vous ne pouvez pas avoir de constructeurs, utilisez donc soit memsetou - la solution intéressante - les initialiseurs désignés:
Je crois que c'est C, pas C ++. Il ne parviendra pas à compiler sous certains compilateurs C ++. J'ai rencontré l'échec de la compilation sous Cygwin ou MinGW.
2015
3
Je crois que la bonne réponse est que leurs valeurs ne sont pas définies. Souvent, ils sont initialisés à 0 lors de l'exécution des versions de débogage du code. Ce n'est généralement pas le cas lors de l'exécution des versions.
Même chose pour le double; all-bits-zero n'est pas nécessairement 0,0. Cependant, vous pouvez vérifier si vous avez des doubles IEEE754, auquel cas cela doit fonctionner.
MSalters
1
Déplacez les membres du pod vers une classe de base pour raccourcir votre liste d'initialisation:
Réponses:
Ils ne sont pas nuls si vous n'initialisez pas la structure.
Le second mettra tous les membres à zéro, le premier les laisse à des valeurs non spécifiées. Notez qu'il est récursif:
Le second fera
p.s.{x,y}
zéro. Vous ne pouvez pas utiliser ces listes d'initialisation agrégées si vous avez des constructeurs dans votre structure. Si tel est le cas, vous devrez ajouter une bonne initialisation à ces constructeursInitialise à la fois x et y à 0. Notez que vous pouvez utiliser
x(), y()
pour les initialiser sans tenir compte de leur type: c'est alors l'initialisation de la valeur, et donne généralement une valeur initiale correcte (0 pour int, 0,0 pour double, appelant le constructeur par défaut pour défini par l'utilisateur types qui ont des constructeurs déclarés par l'utilisateur, ...). Ceci est important surtout si votre structure est un modèle.la source
Snapshot s = {};
pour les non-membres du POD (pour les mettre à zéro)?Non, ils ne sont pas 0 par défaut. Le moyen le plus simple de s'assurer que toutes les valeurs ou par défaut à 0 est de définir un constructeur
Cela garantit que toutes les utilisations de Snapshot auront des valeurs initialisées.
la source
En général, non. Cependant, une structure déclarée comme portée de fichier ou statique dans une fonction / sera / sera initialisée à 0 (comme toutes les autres variables de ces étendues):
la source
Avec POD, vous pouvez également écrire
Vous ne devez pas utiliser memset en C ++, memset a l'inconvénient que s'il y a un non-POD dans la structure, il le détruira.
ou comme ça:
la source
SomeType foo();
c'est le cas typique, bien que cela puisse arriver avec d'autres - en définitions de fonctions (dans ce cas, une fonctionfoo
qui revientSomeType
). Désolé pour la nécro, mais si quelqu'un d'autre tombe dessus, j'ai pensé que je répondrais.En C ++, utilisez des constructeurs sans argument. En C, vous ne pouvez pas avoir de constructeurs, utilisez donc soit
memset
ou - la solution intéressante - les initialiseurs désignés:la source
Je crois que la bonne réponse est que leurs valeurs ne sont pas définies. Souvent, ils sont initialisés à 0 lors de l'exécution des versions de débogage du code. Ce n'est généralement pas le cas lors de l'exécution des versions.
la source
0
dans ces emplacements en mémoire. Ce n'est pas la même chose que l'initialisation!Comme il s'agit d'un POD (essentiellement une structure C), il n'y a pas de mal à l'initialiser de la manière C:
ou similaire
Je n'irais pas jusqu'à utiliser
calloc()
dans un programme C ++.la source
Déplacez les membres du pod vers une classe de base pour raccourcir votre liste d'initialisation:
la source