86 votes

Pourquoi le compilateur lance-t-il cet avertissement: "initialiseur manquant"? La structure n'est-elle pas initialisée?

Je suis de la création d'une sorte de page de garde pour un programme. Pour lancer le programme que je suis en utilisant l'appel CreateProcess(), ce qui, entre autres choses, reçoit un pointeur vers une STARTUPINFO de la structure. Pour initialiser la structure que j'ai utilisé pour le faire:

STARTUPINFO startupInfo = {0}; // Or even '\0'.
startupInfo.cb = sizeof(startupInfo);

Lors de la compilation du programme avec GCC en permettant à ces ensembles d'avertissements -Wall -Wextra il me donne un message d'avertissement disant qu'il y a un manque d'initialiseur pointant vers la première ligne.

warning: missing initializer
warning: (near initialization for 'startupInfo.lpReserved')

J'ai donc fini par le faire:

STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);

Et de cette façon, le compilateur ne donne pas d'avertissement.
La question est, quelle est la différence entre ces façons de l'initialisation d'une structure?
À l'aide de la première méthode, n'est-ce pas la structure initialisée?
Qui voulez-vous recommander?

Merci pour votre temps.

P. S.: Désolé pour le titre, je ne pouvais pas penser à un meilleur.

90voto

Michael Burr Points 181287

GCC est juste d'être trop paranoïaque pour aucune bonne raison à mon avis, mais il est certainement vrai que la GCC responsables d'en apprendre beaucoup plus sur les nuances de C ce que je fais.

Voir ce petit fil de discussion sur le problème de la GCC liste de diffusion:

La ligne de fond de bien - initialisation de la structure avec juste {0} sera en fait zéro initialiser l'ensemble de la chose.

Le standard C99 dit ce qui suit dans 6.7.8/21 "Initialisation - Sematics":

Si il y a moins d'initialiseurs dans un corset-ci-joint la liste qu'il y a des éléments ou des membres d'un agrégat, ou moins de caractères dans une chaîne littérale utilisée pour initialiser un tableau de taille connue qu'il y a d'éléments dans le tableau, le reste de la somme doit être initialisé implicitement le même que les objets qui ont statique de la durée de stockage.

C90 dit esentially la même dans 6.5.7 avec un peu différentes formulations (en d'autres termes, C99 n'ai pas ajouter quelque chose de nouveau ici).

Notez également qu'en C++, cela a été élargie de manière à ce qu'un ensemble vide de croisillons, "{}", serait de effectuer l'initialisation par défaut sur un objet, car il y a des situations (comme les modèles) lorsque vous ne savez même pas ce que les membres ou combien de membres d'un type peut avoir. Ainsi, non seulement est-il une bonne pratique, mais nécessaire à la fois d'avoir un initialiseur liste est plus courte que le nombre de membres d'un objet pourrait avoir.

26voto

dmityugov Points 2786

Ceci peut être facilement corrigé pour les programmes GCC dans C ++ en initialisant la structure en tant que

 STARTUPINFO startupInfo = STARTUPINFO();
 
  • vient de faire exactement cela il y a quelques jours

17voto

ecotax Points 437

Vous avez demandé autant d'avertissements que possible à l'aide de -Wall -Wextra.

Dans ce cas, vous recevez un avertissement vous indiquant que vous n'avez pas spécifié tous les champs, ce qui est parfaitement valide, mais aurait pu être involontaire.

Vous pouvez supprimer cet avertissement en ajoutant -Wno-missing-field-initializers

14voto

JanX2 Points 566

Cette page Web traite en détail du problème sous-jacent: http://ex-parrot.com/~chris/random/initialise.html

En guise de solution de contournement, ma solution actuelle consiste à supprimer de manière sélective cet avertissement:

 #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
STARTUPINFO startupInfo = {0};
#pragma clang diagnostic pop
 

Malheureusement, cela ne fonctionne que dans les cas graves et ne semble pas fonctionner dans GCC.

1voto

En C ++, vous pouvez utiliser boost::initialized_value pour supprimer cet avertissement. J'ai des avertissements désactivés pour boost ; donc je ne sais pas si cela provoquerait d'autres avertissements dans votre cas. De cette façon, vous ne devez pas désactiver l'avertissement.

Exemple:

 T bla = boost::initialized_value;
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X