En Visual C ++, il est possible d'utiliser #pragma warning (disable: ...)
. J'ai également constaté que dans GCC, vous pouvez remplacer les drapeaux du compilateur par fichier . Comment est-ce que je peux faire ceci pour la "ligne suivante", ou avec la sémantique push / pop autour des zones de code en utilisant GCC?
c
gcc
compiler-warnings
pragma
Matt Joiner
la source
la source
Réponses:
Il semble que cela puisse être fait . Je ne peux pas déterminer la version de GCC qui a été ajoutée, mais c'était avant juin 2010.
Voici un exemple:
la source
push
et deuxpop
s - peut-être un autrepush
au début est manquant?Pour tout supprimer, voici un exemple de désactivation temporaire d' un avertissement:
Vous pouvez consulter la documentation GCC sur les pragmas de diagnostic pour plus de détails.
la source
gcc-4.9
ignore complètement cette ligne.TL; DR : si cela fonctionne, évitez ou utilisez des spécificateurs comme
__attribute__
, sinon_Pragma
.Ceci est une version courte de mon article de blog Suppression des avertissements dans GCC et Clang .
Considérer ce qui suit
Makefile
pour construire le
puts.c
code source suivantIl ne se compilera pas car il
argc
n'est pas utilisé et les paramètres sont inconditionnels (-W -Wall -pedantic -Werror
).Vous pouvez faire 5 choses:
__attribute__
_Pragma
#pragma
Améliorer la source
La première tentative devrait être de vérifier si le code source peut être amélioré pour se débarrasser de l'avertissement. Dans ce cas, nous ne voulons pas changer l'algorithme juste à cause de cela, comme
argc
c'est redondant avec!*argv
(NULL
après le dernier élément).Utilisation d'un spécificateur de déclaration, comme
__attribute__
Si vous avez de la chance, la norme fournit un spécificateur pour votre situation, comme
_Noreturn
.__attribute__
est une extension GCC propriétaire (prise en charge par Clang et certains autres compilateurs commearmcc
) et ne sera pas comprise par de nombreux autres compilateurs. Mettez à l'__attribute__((unused))
intérieur d'une macro si vous voulez du code portable._Pragma
opérateur_Pragma
peut être utilisé comme alternative à#pragma
.Le principal avantage de l'
_Pragma
opérateur est qu'il peut être placé dans des macros, ce qui n'est pas possible avec la#pragma
directive.Inconvénient: c'est presque un nucléaire tactique, car il fonctionne en ligne plutôt qu'en déclaration.
L'
_Pragma
opérateur a été introduit en C99.#pragma
directif.Nous pourrions changer le code source pour supprimer l'avertissement pour une région de code, généralement une fonction entière:
Inconvénient: c'est presque un nucléaire tactique, car il fonctionne en ligne plutôt qu'en déclaration.
Notez qu'une syntaxe similaire existe dans clang .
Suppression de l'avertissement sur la ligne de commande pour un seul fichier
Nous pourrions ajouter la ligne suivante à
Makefile
pour supprimer l'avertissement spécifiquement pour les put :Ce n'est probablement pas ce que vous voulez dans votre cas particulier, mais cela peut aider d'autres lectures qui se trouvent dans des situations similaires.
la source
improving the source
il serait également utile de changer la déclaration de mainint main(int, const char* argv[]) { ... }
en ne donnant pas de nom à l'argument, vous dites au compilateur qu'il ne sera pas utilisé.gcc
aussi bien queclang
.#define UNUSED(x) ((void)x)
utilisée pour faire taire les avertissements. Je pense que c'était dans ReactOS?_Pragma("GCC diagnostic pop") \
devrait juste être_Pragma("GCC diagnostic pop")
je pense.Cela devrait faire l'affaire pour gcc, clang et msvc
Peut être appelé avec par exemple:
voir https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html , http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas et https://msdn.microsoft .com / de-DE / library / d9x1s805.aspx pour plus de détails
Vous avez besoin d'au moins la version 4.02 pour utiliser ce genre de pragmas pour gcc, vous n'êtes pas sûr de msvc et clang sur les versions.
Il semble que la gestion du pragma push pop pour gcc soit un peu cassée. Si vous réactivez l'avertissement, vous obtenez toujours l'avertissement pour le bloc qui était à l'intérieur du bloc DISABLE_WARNING / ENABLE_WARNING. Pour certaines versions de gcc, cela fonctionne, pour d'autres non.
la source
Remplacez "-Wformat" par le nom de votre indicateur d'avertissement.
AFAIK il n'y a aucun moyen d'utiliser la sémantique push / pop pour cette option.
la source
J'ai eu le même problème avec les bibliothèques externes comme les en-têtes ROS. J'aime utiliser les options suivantes dans CMakeLists.txt pour une compilation plus stricte:
Cependant, cela provoque également toutes sortes d'erreurs pédantes dans les bibliothèques incluses en externe. La solution est de désactiver tous les avertissements pédants avant d'inclure des bibliothèques externes et de les réactiver comme ceci:
la source
Je sais que la question concerne GCC, mais pour ceux qui cherchent comment faire cela dans d'autres compilateurs et / ou plusieurs…
TL; DR
Vous voudrez peut-être jeter un œil à Hedley , qui est un en-tête C / C ++ unique du domaine public que j'ai écrit et qui fait beaucoup de choses pour vous. Je mettrai une section rapide sur la façon d'utiliser Hedley pour tout cela à la fin de ce post.
Désactiver l'avertissement
#pragma warning (disable: …)
a des équivalents dans la plupart des compilateurs:#pragma warning(disable:4996)
#pragma GCC diagnostic ignored "-W…"
où les points de suspension sont le nom de l'avertissement; par exemple ,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
.#pragma clang diagnostic ignored "-W…"
. La syntaxe est fondamentalement la même que celle de GCC, et de nombreux noms d'avertissement sont les mêmes (bien que beaucoup ne le soient pas).#pragma warning(disable:1478 1786)
.diag_suppress
pragma:#pragma diag_suppress 1215,1444
diag_suppress
pragma avec la même syntaxe (mais des numéros d'avertissement différents!) Que PGI:pragma diag_suppress 1291,1718
error_messages
pragma. Malheureusement, les avertissements sont différents pour les compilateurs C et C ++. Ces deux désactivent essentiellement les mêmes avertissements:#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
#pragma error_messages(off,symdeprecated,symdeprecated2)
diag_suppress
comme PGI et TI, mais la syntaxe est différente. Certains des numéros d'avertissement sont les mêmes, mais moi d'autres ont divergé:#pragma diag_suppress=Pe1444,Pe1215
#pragma warn(disable:2241)
Pour la plupart des compilateurs, c'est souvent une bonne idée de vérifier la version du compilateur avant d'essayer de la désactiver, sinon vous finirez par déclencher un autre avertissement. Par exemple, GCC 7 a ajouté la prise en charge de l'
-Wimplicit-fallthrough
avertissement, donc si vous vous souciez de GCC avant 7, vous devriez faire quelque chose commePour clang et les compilateurs basés sur clang tels que les versions plus récentes de XL C / C ++ et armclang, vous pouvez vérifier si le compilateur connaît un avertissement particulier à l'aide de la
__has_warning()
macro.Bien sûr, vous devez également vérifier si la
__has_warning()
macro existe:Vous pourriez être tenté de faire quelque chose comme
Vous pouvez donc utiliser
__has_warning
un peu plus facilement. Clang suggère même quelque chose de similaire pour la__has_builtin()
macro dans leur manuel. Ne fais pas ça . Un autre code peut vérifier__has_warning
et retomber sur la vérification des versions du compilateur s'il n'existe pas, et si vous définissez,__has_warning
vous casserez leur code. La bonne façon de procéder consiste à créer une macro dans votre espace de noms. Par exemple:Ensuite, vous pouvez faire des choses comme
Pousser et éclater
De nombreux compilateurs prennent également en charge un moyen de pousser et d'afficher les avertissements sur une pile. Par exemple, cela désactivera un avertissement sur GCC pour une ligne de code, puis le ramènera à son état précédent:
Bien sûr, il n'y a pas beaucoup d'accord entre les compilateurs sur la syntaxe:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
#pragma clang diagnostic push
/#pragma diagnostic pop
#pragma warning(push)
/#pragma warning(pop)
#pragma warning(push)
/#pragma warning(pop)
#pragma push
/#pragma pop
#pragma diag_push
/#pragma diag_pop
#pragma warning(push)
/#pragma warning(pop)
Si la mémoire est bonne, pour certaines versions très anciennes de GCC (comme 3.x, IIRC), les pragmas push / pop devaient être en dehors de la fonction.
Cacher les détails sanglants
Pour la plupart des compilateurs, il est possible de masquer la logique derrière les macros à l'aide de
_Pragma
, qui a été introduite dans C99. Même en mode non-C99, la plupart des compilateurs prennent en charge_Pragma
; la grande exception est MSVC, qui a son propre__pragma
mot-clé avec une syntaxe différente. La norme_Pragma
prend une chaîne, la version de Microsoft ne:Est à peu près équivalent, une fois prétraité, à
Cela nous permet de créer des macros afin que nous puissions écrire du code comme
Et cachez tous les vilains contrôles de version dans les définitions de macro.
La manière la plus simple: Hedley
Maintenant que vous comprenez la mécanique de la façon de faire des trucs comme ça tout en gardant votre code propre, vous comprenez ce que fait un de mes projets, Hedley . Au lieu de fouiller dans des tonnes de documentation et / ou d'installer autant de versions du plus grand nombre de compilateurs que possible pour tester, vous pouvez simplement inclure Hedley (c'est un seul en-tête C / C ++ du domaine public) et en finir avec. Par exemple:
Désactivera l'avertissement concernant l'appel d'une fonction obsolète sur GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles et peut-être d'autres (je ne prendrai probablement pas la peine de mettre à jour cette réponse car je mets à jour Hedley). Et, sur les compilateurs qui ne sont pas connus pour fonctionner, les macros seront prétraitées à rien, donc votre code continuera à fonctionner avec n'importe quel compilateur. Bien sûr, ce
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
n'est pas le seul avertissement dont Hedley est au courant, ni la désactivation des avertissements que tout Hedley peut faire, mais j'espère que vous avez l'idée.la source
Plutôt que de faire taire les avertissements, le style gcc consiste généralement à utiliser des constructions C standard ou l'
__attribute__
extension pour informer le compilateur de votre intention. Par exemple, l'avertissement concernant l'affectation utilisée comme condition est supprimé en mettant l'affectation entre parenthèses, c'est-à-direif ((p=malloc(cnt)))
au lieu deif (p=malloc(cnt))
. Les avertissements sur les arguments de fonctions inutilisés peuvent être supprimés par des bizarreries dont__attribute__
je ne me souviens jamais, ou par auto-affectation, etc. Mais généralement je préfère simplement désactiver globalement toute option d'avertissement qui génère des avertissements pour les choses qui se produiront dans le code correct.la source
if ((p=malloc(cnt)) != NULL) ...
que c'est ce que fait le compilateur en arrière-plan.Pour ceux qui ont trouvé cette page à la recherche d'un moyen de le faire dans IAR, essayez ceci:
Voir http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html pour référence.
la source