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:
- MSVC:
#pragma warning(disable:4996)
- GCC:
#pragma GCC diagnostic ignored "-W…"
où les points de suspension sont le nom de l'avertissement; par exemple , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
.
- clang:
#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).
- Intel C Compiler: utilisez la syntaxe MSVC, mais gardez à l'esprit que les numéros d'avertissement sont totalement différents. Exemple:
#pragma warning(disable:1478 1786)
.
- IGP: Il y a un
diag_suppress
pragma:#pragma diag_suppress 1215,1444
- TI: Il existe un
diag_suppress
pragma avec la même syntaxe (mais des numéros d'avertissement différents!) Que PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): il y a un
error_messages
pragma. Malheureusement, les avertissements sont différents pour les compilateurs C et C ++. Ces deux désactivent essentiellement les mêmes avertissements:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR: utilise également
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
- Pelles C: similaire à MSVC, mais encore une fois les chiffres sont différents
#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 comme
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Pour 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.
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Bien sûr, vous devez également vérifier si la __has_warning()
macro existe:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Vous pourriez être tenté de faire quelque chose comme
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
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:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Ensuite, vous pouvez faire des choses comme
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
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:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Bien sûr, il n'y a pas beaucoup d'accord entre les compilateurs sur la syntaxe:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- clang:
#pragma clang diagnostic push
/#pragma diagnostic pop
- Intel 13+ (et probablement plus tôt):
#pragma warning(push)
/#pragma warning(pop)
- MSVC 15+ (VS 9.0 / 2008):
#pragma warning(push)
/#pragma warning(pop)
- ARM 5.6+:
#pragma push
/#pragma pop
- TI 8.1+:
#pragma diag_push
/#pragma diag_pop
- Pelles C 2.90+ (et probablement plus tôt):
#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:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Est à peu près équivalent, une fois prétraité, à
#pragma foo
Cela nous permet de créer des macros afin que nous puissions écrire du code comme
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
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:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
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.