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?

158
demandé sur Matt Joiner 2010-07-31 18:41:39

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 */
172
répondu Matt Joiner 2010-08-03 07:06:59

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.

76
répondu Ian Pilcher 2016-01-20 14:08:22
#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.

14
répondu Joe D 2010-07-31 14:59:54
#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.

12
répondu Martin Gerhardy 2016-03-23 10:02:55

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.

8
répondu Christian Hujer 2017-11-27 19:51:57

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
4
répondu ShitalShah 2016-04-26 05:53:13

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.

2
répondu R.. 2010-07-31 15:28:49

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.

2
répondu Keron 2016-09-20 00:23:24