Как отключить предупреждения 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 Для справки.