Comment supprimer les avertissements GCC des en-têtes de bibliothèque?

126

J'ai un projet qui utilise des bibliothèques log4cxx, boost, etc. dont les en-têtes génèrent de nombreux avertissements (répétitifs). Existe-t-il un moyen de supprimer les avertissements des inclusions de bibliothèque (c'est-à-dire #include <some-header.h>) ou des inclusions de certains chemins? Je voudrais utiliser -Wall et / ou -Wextra comme d'habitude sur le code du projet sans que les informations pertinentes soient masquées. J'utilise actuellement grep sur make output mais j'aimerais quelque chose de mieux.

AdSR
la source

Réponses:

127

Vous pouvez essayer d'inclure les en-têtes de bibliothèque en utilisant -isystemau lieu de -I. Cela en fera des "en-têtes système" et GCC ne rapportera pas d'avertissement pour eux.

Phi
la source
11
Si vous essayez de faire cela dans XCode, collez -isystem path dans vos "autres indicateurs C ++" dans les "indicateurs de compilateur personnalisés" dans vos paramètres de construction cible.
Matt Parkins du
3
Un inconvénient potentiel est que sur certaines plates-formes, g ++ encapsulera automatiquement tous les en-têtes système extern "C", conduisant à des erreurs étranges sur la liaison C si vous avez #includeun en-tête C ++ dans un -isystemchemin.
Tavian Barnes
1
+1 m'a aidé à résoudre des problèmes avec des avertissements de boost ennuyeux stackoverflow.com/questions/35704753/warnings-from-boost
mrgloom
3
Pourquoi cela a-t-il autant de votes que la propre réponse du PO qui disait exactement la même chose une heure et demie plus tôt?
underscore_d
1
Pour Xcode: que faire s'il n'y avait pas de chemin de dossier dans «Autres indicateurs C ++» dans mes paramètres de construction cible? Quelqu'un pourrait-il élaborer sur ces solutions?
Ossir
107

Pour ceux qui utilisent CMake, vous pouvez modifier vos include_directoriesdirectives pour inclure le symbole SYSTEMqui supprime les avertissements contre de tels en-têtes.

include_directories(SYSTEM "${LIB_DIR}/Include")
                    ^^^^^^
Drew Noakes
la source
Que faire si la bibliothèque fournit une ${LIBFOO_USE_FILE}variable à utiliser avec la commande include () de CMake ?
waldyrious
2
Cela semble être presque la solution à mon problème. J'ai 1.) une cible binaire, qui dépend de 2.) une cible d'en-tête uniquement écrite par moi-même, qui dépend de 3.) certaines bibliothèques externes. Je ne sais pas comment obtenir uniquement des avertissements pour 1 et 2. Vous avez des idées?
knedlsepp
2
Cela ne semble pas fonctionner. J'ai essayé cela avec un projet qui utilise easylogging++et j'obtiens la même énorme quantité d'avertissements de la easylogging++.hmême si le dossier où il réside a été inclus avec l' SYSTEMoption.
rbaleksandar
Merci beaucoup pour cela. Cela m'a sauvé des pages et des pages d'avertissements.
Svalorzen
1
Même commentaire que pour la réponse acceptée: c'est une mauvaise pratique pour moi.
Raffi
55

Vous pouvez utiliser des pragmas. Par exemple:

// save diagnostic state
#pragma GCC diagnostic push 

// turn off the specific warning. Can also use "-Wall"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

// turn the warnings back on
#pragma GCC diagnostic pop
andrewrjones
la source
3
Uniquement disponible avec GCC> = 4.6
Caduchon
1
J'adore la capacité des pragmas push / pop. je me souviens de quelque chose comme pour java disponible il y a des années et être frustré / jaloux pour C / C ++. J'adore que cela soit disponible dansgcc
Trevor Boyd Smith
@TrevorBoydSmith MS en cla aussi la capacité depuis des années ... Parfois, gccc'est un peu lent à s'adapter.
Alexis Wilke
29

J'ai trouvé le truc. Pour la bibliothèque inclut, au lieu de l' -Idirutiliser -isystem dirdans le makefile. GCC traite alors boost etc. comme le système inclut et ignore tout avertissement de leur part.

AdSR
la source
Notez que si vous utilisez un en-tête précompilé, vous devez ajouter l'indicateur lorsque vous compilez à la fois l'en-tête et le code.
user202729
9

#pragmasont des instructions au compilateur. vous pouvez définir quelque chose avant le #include et le désactiver après.

Vous pouvez également le faire en ligne de commande .

Une autre page GCC spécifiquement sur la désactivation des avertissements .

J'opterais pour l'option d'utiliser # pragma dans le code source, puis de fournir un son raison (en commentaire) de la raison pour laquelle vous désactivez les avertissements. Cela impliquerait un raisonnement sur les fichiers d'en-têtes.

GCC aborde cela en classant les types d'avertissement. Vous pouvez les classer comme avertissements ou pour être ignorés. Les articles précédemment liés vous montreront quels avertissements peuvent être désactivés.

Remarque: vous pouvez également masser le code source pour éviter certains avertissements en utilisant des attributs ; cependant, cela vous lie assez étroitement à GCC.

Note 2: GCC utilise également l' interface pop / push telle qu'utilisée dans le compilateur de Microsoft - Microsoft désactive les avertissements via cette interface. Je vous suggère d'enquêter plus avant, car je ne sais pas si c'est même possible.

Hassan Syed
la source
J'ai envisagé les pragmas, mais si je supprime un avertissement avant d'inclure un en-tête, comment le remettre à l' état précédent après #include? Je veux voir tous les avertissements pour le code du projet (m'a aidé déjà quelques fois) mais avoir le contrôle de la ligne de commande.
AdSR
4

Vous pouvez essayer d'utiliser des en- têtes précompilés . Les avertissements ne disparaîtront pas, mais au moins ils n'apparaîtront pas dans votre compilation principale.

Pablo Santa Cruz
la source
1
Cela pourrait en fait être une bonne idée. Les tiers inclus ne changent pas tous les jours.
AdSR
Exactement. Bien que je ne les ai pas beaucoup utilisés sous Linux, ils fonctionnent plutôt bien sur Visual Studio.
Pablo Santa Cruz
Non, ils apparaîtront toujours dans la compilation à moins que vous n'utilisiez un autre moyen de les supprimer (comme -isystem, mais n'oubliez pas de l'utiliser à la fois pour compiler l'en-tête et dans le code)
user202729
2

Si vous avez besoin de remplacer explicitement un en-tête système, vous êtes limité aux pragmas. Vous pouvez vérifier les inclusions que vous utilisez via la make dependsortie.

Voir également le diagnostic push-pop pour gcc> = 4.6

supaflav
la source
1

Mettre ce qui suit

#pragma GCC system_header

désactivera les avertissements GCC pour tout le code suivant dans ce fichier.

Evgenii
la source
-9

Il doit y avoir des raisons à ces avertissements. Celles-ci seront soit causées par des erreurs dans votre code qui utilise la bibliothèque, soit par des erreurs dans le code de la bibliothèque lui-même. Dans le premier cas, corrigez votre code. Dans le second cas, arrêtez d'utiliser la bibliothèque ou s'il s'agit de code FOSS, corrigez-le.


la source
+1 pour un bon conseil: D mais il demande comment faire quelque chose de spécifique: D
Hassan Syed
4
Certains avertissements sont impossibles ou très difficiles à corriger, en particulier dans le code tiers, en particulier dans le code riche en métaprogrammation comme celui de Boost.
ulidtko
3
Pire encore, celui qui me dérange est "la déclaration de 'c' ombres un membre de 'this' [-Werror = shadow]" profondément, profondément dans un en-tête de boost. Ce n'est certainement pas un problème, mais cela et des problèmes similaires crachent la sortie et il m'est difficile de trouver des instances une véritable ombre dans notre base de code.
dmckee --- ex-moderator chaton