Pourquoi je reçois le message “warning: missing initialiseur de membre”? [-Wmissing-champ-des initialiseurs]
Je me demande pourquoi je reçois un avertissement au sujet de l'initialisation dans un cas mais pas dans l'autre. Le code est dans un fichier source C++, et en utilisant GCC 4.7 avec -std=c++11
.
struct sigaction old_handler, new_handler;
Ci-dessus produit PAS avertissements avec -Wall
et -Wextra
.
struct sigaction old_handler={}, new_handler={};
struct sigaction old_handler={0}, new_handler={0};
Ci-dessus produit des avertissements:
warning: missing initializer for member ‘sigaction::__sigaction_handler’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_mask’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_flags’ [-Wmissing-field-initializers]
warning: missing initializer for member ‘sigaction::sa_restorer’ [-Wmissing-field-initializers]
J'ai lu à travers Comment dois-je initialiser correctement un C struct en C++?, Pourquoi le compilateur de lancer cet avertissement: "manque d'initialiseur"? N'est-ce pas la structure initialisée?, et les rapports de bug comme http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750. Je ne comprends pas pourquoi les non initialisée struct n'est pas générer un avertissement, alors que la initialisée struct est générer un avertissement.
Pourquoi le non initialisée les structures de ne pas générer un avertissement; et pourquoi est initialisé les structures générer un avertissement?
- Ce que vous appelez initialisée est que partiellement initialisé, donc l'avertissement.
- Double de Pourquoi le compilateur de lancer cet avertissement: “manque d'initialiseur”? N'est-ce pas la structure initialisée?, mais je ne suis pas autorisé à fermer la question. Soupir...
Vous devez vous connecter pour publier un commentaire.
Voici un exemple simple:
Il donne cet avertissement:
Le programme imprime:
L'avertissement est juste un rappel à partir du compilateur qui
S
a deux membres, mais vous ne explicitement initialisée l'un d'eux, l'autre sera mis à zéro. Si c'est ce que vous voulez, vous pouvez ignorer cet avertissement.Dans ce simple exemple, il semble stupide et ennuyeux; si votre structure a beaucoup de membres, alors cet avertissement peut être utile (la capture des bugs: les erreurs de comptage du nombre de champs ou des fautes de frappe).
Je suppose que ce serait tout simplement de générer trop de mises en garde. Après tout, c'est légal et c'est seulement un bug si vous utilisez le non initialisée membres. Par exemple:
Même si elle n'a pas de m'avertir au sujet de la non initialisée membres de
s
, il ne me mettent en garde sur l'utilisation de la non initialisée champs. Tout est très bien.Il ne vous avertit que si vous l'avez explicitement mais partiellement initialiser les champs. C'est un rappel que la structure a plus de champs que vous avez énuméré. À mon avis, on peut se demander quelle est l'utilité de cet avertissement: Il peut en effet générer trop de fausses alarmes. Eh bien, il n'est pas activé par défaut pour une raison...
C'est un défaut d'avertissement. Vous n'avez initialiser tous les membres, vous venez de ne pas avoir les initialiseurs pour chaque membre séparément apparaissent dans le code.
Simplement ignorer cet avertissement, si vous savez ce que vous faites. Je reçois régulièrement de tels avertissements trop, et je suis bouleversé régulièrement. Mais il n'y a rien que je puisse faire à ce sujet, mais de l'ignorer.
Pourquoi le non initialisée struct ne pas donner un avertissement? Je ne sais pas, mais plus que probablement, c'est parce que vous n'avez pas essayez d'initialiser quoi que ce soit. Donc GCC a aucune raison de croire que vous avez fait une erreur dans l'exécution de l'initialisation.
Le compilateur prévient que tous les membres ne sont pas initialisés lors de l'initialisation de la structure. Il n'y a rien à mettre en garde sur le fait de déclarer un non initialisée struct. Vous devriez obtenir les mêmes mises en garde lorsque vous (partiellement) initialiser le non initialisée des structures.
Donc, c'est la différence. Votre code qui ne produisent pas l'avertissement n'est pas une initialisation à tous. Pourquoi gcc met en garde sur zéro initialisé struct est au delà de moi.
Le seul moyen d'empêcher que l'avertissement ou d'erreur, si vous ou votre organisation est le traitement de l'avertissement d'erreur (option-Werror)) est de memset à la valeur initiale. Par exemple:
Pas très propre, cependant, il semble que pour GCC responsables, il n'y a qu'une seule façon d'initialiser une structure de code et de la beauté n'est pas en haut de leur liste.
Vous aidez à résoudre le symptôme mais pas le problème. Par mon exemplaire de "Advanced Programming in the UNIX Environment, Deuxième Édition", à l'article 10.15:
Donc, oui, vous pouvez le silence de l'avertissement, et non ce n'est pas la façon dont vous initialisez une struct sigaction.
sigemptyset
est pas initialisation utilisée en C++ les gens. Habituellement, le dicton est "l'Assignation n'est pas de l'initialisation" en C++, mais je pense que les états-unis desigemptyset
est similaire.