Как отключить предупреждения 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 " на имя вашего предупреждающего флага.
насколько мне известно, нет никакого способа, чтобы использовать 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
- используйте параметр командной строки.
улучшение источник
первая попытка должна быть проверка, если исходный код может быть улучшен, чтобы избавиться от предупреждения. В этом случае мы не хотим менять алгоритм только из-за этого, как
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 Для справки.