Comment désactiver les Avertissements GCC pour quelques lignes de code
Dans Visual C++, il est possible d'utiliser #pragma warning (disable: ...)
. Aussi, j'ai trouvé que dans GCC vous pouvez remplacer par les drapeaux du compilateur de fichiers . Comment puis-je faire cela pour la "ligne suivante", ou avec la sémantique push/pop autour des zones de code en utilisant GCC?
8 réponses
Cette peut être fait. Je suis incapable de déterminer la version de GCC qu'il a été ajouté, mais c'était avant juin 2010.
Voici un exemple:
#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop
foo(c); /* error is given for this one */
#pragma GCC diagnostic pop
foo(d); /* depends on command line options */
Pour tout effacer, voici un exemple dedésactivant temporairement un avertissement:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
write(foo, bar, baz);
#pragma GCC diagnostic pop
Vous pouvez consulter la documentation GCC sur les pragmas de diagnostic pour plus de détails.
#pragma GCC diagnostic ignored "-Wformat"
Remplacez "- Wformat " par le nom de votre drapeau d'avertissement.
AFAIK il n'y a aucun moyen d'utiliser la sémantique push/pop pour cette option.
#define DIAG_STR(s) #s
#define DIAG_JOINSTR(x,y) DIAG_STR(x ## y)
#ifdef _MSC_VER
#define DIAG_DO_PRAGMA(x) __pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(warning(x))
#else
#define DIAG_DO_PRAGMA(x) _Pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(compiler diagnostic x)
#endif
#if defined(__clang__)
# define DISABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,push) DIAG_PRAGMA(clang,ignored DIAG_JOINSTR(-W,clang_option))
# define ENABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,pop)
#elif defined(_MSC_VER)
# define DISABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,push) DIAG_DO_PRAGMA(warning(disable:##msvc_errorcode))
# define ENABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,pop)
#elif defined(__GNUC__)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,push) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,pop)
#else
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_option,msvc_unused) DIAG_PRAGMA(GCC,warning DIAG_JOINSTR(-W,gcc_option))
#endif
#endif
Ceci devrait faire l'affaire pour gcc, clang et msvc
Peut être appelé avec, par exemple:
DISABLE_WARNING(unused-variable,unused-variable,42)
[.... some code with warnings in here ....]
ENABLE_WARNING(unused-variable,unused-variable,42)
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, pas sûr de msvc et clang sur le version.
Il semble que la gestion du pragma push pop pour gcc soit un peu cassée. Si vous activez à nouveau l'avertissement, vous obtenez toujours l'avertissement pour le bloc qui se trouvait dans le bloc DISABLE_WARNING/ENABLE_WARNING. Pour certaines versions de gcc, cela fonctionne, pour d'autres non.
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érons ce qui suit Makefile
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
Pour construire le code source puts.c
suivant
#include <stdio.h>
int main(int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
Il ne sera pas compilé car argc
n'est pas utilisé, et les paramètres sont hardcore (-W -Wall -pedantic -Werror
).
Il y a 5 choses que vous pourriez faire:
- améliorer le code source, si possible
- utilisez un spécificateur de déclaration, comme
__attribute__
- Utiliser
_Pragma
- Utiliser
#pragma
- utilisez une option de ligne de commande.
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, car argc
est redondant avec !*argv
(NULL
après le dernier élément).
Utilisation d'un spécificateur de déclaration, comme __attribute__
#include <stdio.h>
int main(__attribute__((unused)) int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
Si vous avez de la chance, la norme fournit un spécificateur pour votre situation, comme _Noreturn
.
__attribute__
est une extension GCC propriétaire (supportée par Clang et d'autres compilateurs comme armcc
également) et ne sera pas comprise par de nombreux autres compilateurs. Mettez __attribute__((unused))
dans une macro si vous voulez du code portable.
_Pragma
opérateur
_Pragma
peut être utilisé comme une alternative à #pragma
.
#include <stdio.h>
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
int main(int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
_Pragma("GCC diagnostic pop") \
Le principal avantage de l'opérateur _Pragma
est que vous pourrait le mettre dans des macros, ce qui n'est pas possible avec la directive #pragma
.
Inconvénient: c'est presque une arme nucléaire tactique, car elle fonctionne en ligne au lieu de declaration-baesd.
L'opérateur _Pragma
a été introduit en C99.
#pragma
directive.
Nous pourrions changer le code source pour supprimer l'avertissement pour une région de code, généralement une fonction entière:
#include <stdio.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, const char *argv[])
{
while (*++argc) puts(*argv);
return 0;
}
#pragma GCC diagnostic pop
Inconvénient: c'est presque une arme nucléaire tactique, car elle fonctionne en ligne au lieu de déclaration-baesd.
Suppression de l'avertissement sur la ligne de commande pour un seul fichier
, Nous pourrions ajouter la ligne suivante à la Makefile
pour supprimer l'avertissement spécialement pour met:
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
puts.o: CPPFLAGS+=-Wno-unused-parameter
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.
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:
set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")
Cependant, cela provoque toutes sortes d'erreurs pédantes dans les bibliothèques externes incluses. 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:
//save compiler switches
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
//Bad headers with problem goes here
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
//restore compiler switches
#pragma GCC diagnostic pop
Plutôt que de faire taire les Avertissements, le style gcc consiste généralement à utiliser des constructions C standard ou l'extension __attribute__
pour en dire plus au compilateur sur votre intention. Par exemple, l'avertissement sur l'affectation utilisé comme condition est supprimé en mettant l'affectation entre parenthèses, c'est-à-dire if ((p=malloc(cnt)))
au lieu de if (p=malloc(cnt))
. Les avertissements sur les arguments de fonction inutilisés peuvent être supprimés par un __attribute__
Impair dont je ne me souviens jamais, ou par auto-affectation, etc. Mais en général je préfère simplement désactiver globalement tout option d'avertissement qui génère des avertissements pour les choses qui se produiront dans le code correct.
Pour ceux qui ont trouvé cette page à la recherche d'un moyen de le faire dans IAR, essayez ceci:
#pragma diag_suppress=Pe177
void foo1( void )
{
/* The following line of code would normally provoke diagnostic
message #177-D: variable "x" was declared but never referenced.
Instead, we have suppressed this warning throughout the entire
scope of foo1().
*/
int x;
}
#pragma diag_default=Pe177
Voir http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html pour référence.