Quand {0}
est utilisé pour initialiser un objet, qu'est-ce que cela signifie? Je ne trouve aucune référence à {0}
quelque part, et à cause des accolades bouclées, les recherches Google ne sont pas utiles.
Exemple de code:
SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;
if(ShellExecuteEx(&sexi))
{
DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
if(wait == WAIT_OBJECT_0)
GetExitCodeProcess(sexi.hProcess, &returnCode);
}
Sans cela, le code ci-dessus plantera lors de l'exécution.
Une chose à savoir est que cette technique ne mettra pas à zéro les octets de remplissage. Par exemple:
N'est pas la même chose que:
Dans le premier cas, les octets de remplissage entre c et i ne sont pas initialisés. Pourquoi voudriez-vous vous en soucier? Eh bien, si vous enregistrez ces données sur le disque ou les envoyez sur un réseau ou autre, vous pourriez avoir un problème de sécurité.
la source
Notez qu'un initialiseur d'agrégat vide fonctionne également:
la source
En réponse à pourquoi
ShellExecuteEx()
se bloque: votreSHELLEXECUTEINFO
structure "sexi" a de nombreux membres et vous n'en initialisez que certains.Par exemple, le membre
sexi.lpDirectory
peut pointer n'importe où, maisShellExecuteEx()
essaiera toujours de l'utiliser, vous obtiendrez donc une violation d'accès à la mémoire.Lorsque vous incluez la ligne:
avant le reste de la configuration de votre structure, vous dites au compilateur de mettre à zéro tous les membres de la structure avant d'initialiser ceux qui vous intéressent.
ShellExecuteEx()
sait que sisexi.lpDirectory
zéro, il doit l'ignorer.la source
Je l'utilise également pour initialiser des chaînes, par exemple.
la source
{0}
est un initialiseur valide pour tout type (objet complet), à la fois en C et C ++. C'est un idiome commun utilisé pour initialiser un objet à zéro (lisez la suite pour voir ce que cela signifie).Pour les types scalaires (types arithmétiques et pointeurs), les accolades ne sont pas nécessaires, mais elles sont explicitement autorisées. Citant le projet N1570 de la norme ISO C, section 6.7.9:
Il initialise l'objet à zéro (
0
pour les entiers,0.0
pour les virgules flottantes, un pointeur nul pour les pointeurs).Pour les types non scalaires (structures, tableaux, unions),
{0}
spécifie que le premier élément de l'objet est initialisé à zéro. Pour les structures contenant des structures, des tableaux de structures, etc., cela est appliqué de manière récursive, de sorte que le premier élément scalaire est défini sur zéro, en fonction du type. Comme dans tout initialiseur, tous les éléments non spécifiés sont mis à zéro.Les accolades intermédiaires (
{
,}
) peuvent être omises; par exemple, les deux sont valides et équivalents:c'est pourquoi vous n'avez pas à écrire, par exemple,
{ { 0 } }
pour un type dont le premier élément est non scalaire.Donc ça:
est une manière abrégée d'initialiser
obj
à zéro, ce qui signifie que chaque sous-objet scalaire deobj
est défini0
si c'est un entier,0.0
s'il est à virgule flottante, ou un pointeur nul si c'est un pointeur.Les règles sont similaires pour C ++.
Dans votre cas particulier, puisque vous attribuez des valeurs à
sexi.cbSize
et ainsi de suite, il est clair qu'ilSHELLEXECUTEINFO
s'agit d'un type de structure ou de classe (ou peut-être une union, mais probablement pas), donc tout cela ne s'applique pas, mais comme je l'ai dit, il{ 0 }
est courant idiome qui peut être utilisé dans des situations plus générales.Ce n'est pas (nécessairement) équivalent à utiliser
memset
pour définir la représentation de l'objet sur tous les bits à zéro. Ni virgule flottante0.0
ni pointeur nul n'est nécessairement représenté comme un zéro sur tous les bits, et un{ 0 }
initialiseur ne définit pas nécessairement les octets de remplissage à une valeur particulière. Sur la plupart des systèmes, cependant, cela aura probablement le même effet.la source
{0}
n'est pas un initialiseur valide pour un objet sans constructeur acceptant0
; ni pour un agrégat dont le premier élément est en tant que tel (ou un agrégat sans élément)Cela fait un moment que je n'ai pas travaillé en c / c ++ mais IIRC, le même raccourci peut également être utilisé pour les tableaux.
la source
Je me suis toujours demandé pourquoi vous devriez utiliser quelque chose comme
Voici un cas de test pour expliquer:
check.c
Je compile avec
gcc -O2 -o check check.c
puis affiche la table des symboles avecreadelf -s check | sort -k 2
(c'est avec gcc 4.6.3 sur ubuntu 12.04.2 sur un système x64). Extrait:La partie importante ici est, c'est
my_zero_struct
après__bss_start
. La section ".bss" dans un programme C est la section de mémoire qui est mise à zéro avant d'main
être appelée voir wikipedia sur .bss .Si vous modifiez le code ci-dessus pour:
Ensuite, l'exécutable "check" résultant a exactement la même apparence au moins avec le compilateur gcc 4.6.3 sur ubuntu 12.04.2; le
my_zero_struct
est toujours dans la.bss
section et il sera donc automatiquement initialisé à zéro, avant d'main
être appelé.Des indications dans les commentaires, selon lesquelles une
memset
initialisation de la structure "complète" n'est pas non plus une amélioration, car la.bss
section est entièrement effacée, ce qui signifie également que la structure "complète" est définie sur zéro.Il se peut que le standard du langage C ne mentionne rien de tout cela, mais dans un compilateur C réel, je n'ai jamais vu un comportement différent.
la source
C'est du sucre syntaxique pour initialiser votre structure entière à des valeurs vides / nulles / nulles.
Version longue
Version courte
N'était-ce pas beaucoup plus facile?
C'est aussi bien parce que:
ZeroMemory
la source
{0} est un tableau anonyme contenant son élément comme 0.
Ceci est utilisé pour initialiser un ou tous les éléments du tableau avec 0.
par exemple int arr [8] = {0};
Dans ce cas, tous les éléments de arr seront initialisés à 0.
la source
{0}
n'est pas un tableau anonyme. Ce n'est même pas une expression. C'est un initialiseur.