Как отключить предупреждения GCC для нескольких строк кода

в Visual C++ можно использовать #pragma warning (disable: ...). Также я обнаружил, что в GCC вы можете переопределить флаги компилятора для каждого файла. Как я могу сделать это для "следующей строки" или с семантикой push/pop вокруг областей кода с помощью GCC?

8 ответов


Это можно сделать. Я не могу определить версию GCC, которая была добавлена, но это было где-то до июня 2010 года.

вот пример:

#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 */

чтобы очистить все, это пример временно отключение предупреждение:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
    write(foo, bar, baz);
#pragma GCC diagnostic pop

вы можете проверить документация ГХК на диагностической прагмы для получения более подробной информации.


#pragma GCC diagnostic ignored "-Wformat"

заменить "- Wformat"на имя предупреждающего флага.

AFAIK для этой опции невозможно использовать семантику push/pop.


#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

Это должно сделать трюк для gcc, clang и msvc

можно вызвать, например:

DISABLE_WARNING(unused-variable,unused-variable,42)
[.... some code with warnings in here ....]
ENABLE_WARNING(unused-variable,unused-variable,42)

см.https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html, http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas и https://msdn.microsoft.com/de-DE/library/d9x1s805.aspx Для больше деталей

вам нужна хотя бы версия 4.02, чтобы использовать такие прагмы для gcc, не уверен msvc и clang о версиях.

похоже, что обработка push pop pragma для gcc немного нарушена. Если вы снова включите предупреждение, вы все равно получите предупреждение для блока, который был внутри блока DISABLE_WARNING/ENABLE_WARNING. Для некоторых версий gcc это работает, для некоторых-нет.


TL; DR: если это работает, избегайте или используйте спецификаторы, такие как __attribute__, иначе _Pragma.

это краткая версия моей статьи в блоге подавление предупреждений в GCC и Clang.

рассмотрим следующее Makefile

CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror

.PHONY: all
all: puts

на строительстве puts.c исходный код

#include <stdio.h>

int main(int argc, const char *argv[])
{
    while (*++argv) puts(*argv);
    return 0;
}

он не будет компилироваться, потому что argc не используется, и параметры хардкор (-W -Wall -pedantic -Werror).

есть 5 вещей, которые вы могли бы сделать:

  • улучшить исходный код, если это возможно
  • используйте спецификатор объявления, например __attribute__
  • использовать _Pragma
  • использовать #pragma
  • используйте параметр командной строки.

улучшение источник

первая попытка должна проверять, можно ли улучшить исходный код, чтобы избавиться от предупреждения. В этом случае мы не хотим чтобы изменить алгоритм только из-за этого, as argc избыточна с !*argv (NULL после последнего элемента).

использование спецификатора объявления, например __attribute__

#include <stdio.h>

int main(__attribute__((unused)) int argc, const char *argv[])
{
    while (*++argv) puts(*argv);
    return 0;
}

Если Вам ПОВЕЗЕТ, стандарт предоставляет спецификатор для вашей ситуации, например _Noreturn.

__attribute__ является проприетарным расширением GCC (поддерживается Clang и некоторыми другими компиляторами, такими как armcc также) и не будут поняты многими другими компиляторами. Положи __attribute__((unused)) внутри макрос, если вам нужен переносимый код.

_Pragma оператор

_Pragma может использоваться в качестве альтернативы #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") \

главные преимущества _Pragma оператор заключается в том, что вы можете поместить его в макросы, что невозможно с помощью


у меня была такая же проблема с внешними библиотеками, как заголовки ROS. Мне нравится использовать следующие параметры в CMakeLists.txt для более строгой компиляции:

set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")

однако это вызывает все виды педантичных ошибок во внешних библиотеках. Решение заключается в отключении всех педантичных предупреждений перед включением внешних библиотек и повторном включении следующим образом:

//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

вместо того, чтобы глушить предупреждения, стиль gcc обычно использует либо стандартные конструкции C, либо


для тех, кто нашел эту страницу, ища способ сделать это в IAR, попробуйте следующее:

#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

см http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html Для справки.