В Visual C ++ это можно использовать #pragma warning (disable: ...)
. Также я обнаружил, что в GCC вы можете переопределить флаги компилятора файлов . Как я могу сделать это для "следующей строки", или с семантикой push / pop вокруг областей кода, используя GCC?
c
gcc
compiler-warnings
pragma
Мэтт Джойнер
источник
источник
Ответы:
Похоже, это можно сделать . Я не могу определить версию GCC, в которую он был добавлен, но это было где-то до июня 2010 года.
Вот пример:
источник
push
и дваpop
с - может быть другогоpush
в начале не хватает?Чтобы вывести все из строя, это пример временного отключения предупреждения:
Вы можете проверить документацию GCC о диагностических прагмах для более подробной информации.
источник
gcc-4.9
просто игнорирует эту строку полностью.TL; DR : если это работает, избегайте или используйте спецификаторы как
__attribute__
, иначе_Pragma
.Это короткая версия моей статьи в блоге « Подавление предупреждений в GCC и Clang» .
Рассмотрим следующее
Makefile
для построения следующего
puts.c
исходного кодаОн не скомпилируется, потому что
argc
он не используется, а настройки хардкорные (-W -Wall -pedantic -Werror
).Есть 5 вещей, которые вы можете сделать:
__attribute__
_Pragma
#pragma
Улучшение источника
Первой попыткой должна быть проверка возможности улучшения исходного кода, чтобы избавиться от предупреждения. В этом случае мы не хотим менять алгоритм только из-за этого, так как
argc
он избыточен!*argv
(NULL
после последнего элемента).Использование спецификатора объявления, например
__attribute__
Если вам повезет, стандарт предоставляет спецификатор для вашей ситуации, например
_Noreturn
.__attribute__
является проприетарным расширением GCC (также поддерживается Clang и некоторыми другими компиляторамиarmcc
) и не будет понято многими другими компиляторами. Поместите__attribute__((unused))
в макрос, если вы хотите переносимый код._Pragma
оператор_Pragma
может быть использован в качестве альтернативы#pragma
.Основное преимущество
_Pragma
оператора заключается в том, что вы можете поместить его в макросы, что невозможно с помощью#pragma
директивы.Недостаток: это почти тактическая ядерная бомба, поскольку она работает на основе строк, а не на основе объявлений.
_Pragma
Оператор был введен в C99.#pragma
директивы.Мы могли бы изменить исходный код, чтобы отключить предупреждение для области кода, обычно всей функции:
Недостаток: это почти тактическая ядерная бомба, поскольку она работает на основе строк, а не на основе объявлений.
Обратите внимание, что подобный синтаксис существует в Clang .
Подавление предупреждения в командной строке для одного файла
Мы могли бы добавить в строку следующую строку,
Makefile
чтобы отключить предупреждение специально для пут:Это, вероятно, не хочет, чтобы вы хотели в вашем конкретном случае, но это может помочь другим чтения, которые находятся в подобных ситуациях.
источник
improving the source
это также сработает, чтобы изменить объявление mainint main(int, const char* argv[]) { ... }
, не задавая аргументу имя, вы сообщаете компилятору, что он не будет использоваться.gcc
, а такжеclang
.#define UNUSED(x) ((void)x)
используется для отключения предупреждений. Я думаю, что это было в ReactOS?_Pragma("GCC diagnostic pop") \
должно быть,_Pragma("GCC diagnostic pop")
я думаю.Это должно сделать трюк для gcc, clang и msvc
Может быть вызван с помощью, например:
см. 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 по поводу версий.
Похоже, что прагм-прагма для gcc немного сломана. Если вы снова включите предупреждение, вы все равно получите предупреждение для блока, который был внутри блока DISABLE_WARNING / ENABLE_WARNING. Для некоторых версий gcc это работает, для некоторых - нет.
источник
Замените «-Wformat» на имя вашего флага предупреждения.
AFAIK нет способа использовать семантику push / pop для этой опции.
источник
У меня была такая же проблема с внешними библиотеками, такими как заголовки ROS. Мне нравится использовать следующие параметры в CMakeLists.txt для более строгой компиляции:
Однако это приводит к всевозможным педантичным ошибкам и во внешних библиотеках. Решение состоит в том, чтобы отключить все педантичные предупреждения, прежде чем включать внешние библиотеки, и снова включить, как это:
источник
Я знаю, что вопрос о GCC, но для людей, которые ищут, как это сделать в других и / или нескольких компиляторах ...
TL; DR
Возможно, вы захотите взглянуть на Hedley , который является одним из общедоступных заголовков C / C ++, который я написал и который делает для вас многое из этого. Я помещу краткий раздел о том, как использовать Хедли для всего этого в конце этого поста.
Отключение предупреждения
#pragma warning (disable: …)
имеет эквиваленты в большинстве компиляторов:#pragma warning(disable:4996)
#pragma GCC diagnostic ignored "-W…"
где многоточие - это название предупреждения; например ,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
.#pragma clang diagnostic ignored "-W…"
. Синтаксис в основном такой же, как в GCC, и многие имена предупреждений совпадают (хотя многие не совпадают).#pragma warning(disable:1478 1786)
.diag_suppress
прагма:#pragma diag_suppress 1215,1444
diag_suppress
прагма с тем же синтаксисом (но с разными номерами предупреждений!), Что и с PGI:pragma diag_suppress 1291,1718
error_messages
прагма. Досадно, что предупреждения для компиляторов C и C ++ различны. Оба из них отключают в основном одни и те же предупреждения:#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
#pragma error_messages(off,symdeprecated,symdeprecated2)
diag_suppress
как PGI и TI, но синтаксис другой. Некоторые номера предупреждений одинаковы, но другие разошлись:#pragma diag_suppress=Pe1444,Pe1215
#pragma warn(disable:2241)
Для большинства компиляторов часто хорошей идеей является проверка версии компилятора, прежде чем пытаться отключить ее, в противном случае вы просто получите другое предупреждение. Например, в GCC 7 добавлена поддержка
-Wimplicit-fallthrough
предупреждения, поэтому, если вы заботитесь о GCC до 7, вы должны сделать что-то вродеДля clang и компиляторов, основанных на clang, таких как более новые версии XL C / C ++ и armclang, вы можете проверить, знает ли компилятор о конкретном предупреждении с помощью
__has_warning()
макроса.Конечно, вы также должны проверить,
__has_warning()
существует ли макрос:Вы можете испытать желание сделать что-то вроде
Таким образом, вы можете использовать
__has_warning
немного проще. Clang даже предлагает нечто подобное для__has_builtin()
макроса в их руководстве. Не делай этого . Другой код может проверять__has_warning
и возвращаться к проверке версий компилятора, если он не существует, и если вы определите,__has_warning
вы нарушите их код. Правильный способ сделать это - создать макрос в вашем пространстве имен. Например:Тогда вы можете делать такие вещи, как
Нажатие и сование
Многие компиляторы также поддерживают способ вставлять предупреждения в стек. Например, это отключит предупреждение в GCC для одной строки кода, а затем вернет его в предыдущее состояние:
Конечно, между компиляторами нет большого согласия по поводу синтаксиса:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
#pragma clang diagnostic push
/#pragma diagnostic pop
#pragma warning(push)
/#pragma warning(pop)
#pragma warning(push)
/#pragma warning(pop)
#pragma push
/#pragma pop
#pragma diag_push
/#pragma diag_pop
#pragma warning(push)
/#pragma warning(pop)
Если память служит, для некоторых очень старых версий GCC (таких как 3.x, IIRC) прагмы push / pop должны быть вне функции.
Сокрытие кровавых деталей
Для большинства компиляторов можно скрыть логику использования макросов
_Pragma
, которая была представлена в C99. Даже в режиме без C99 большинство компиляторов поддерживают_Pragma
; большое исключение - MSVC, у которого есть собственное__pragma
ключевое слово с другим синтаксисом. Стандарт_Pragma
принимает строку, версия Microsoft не:Примерно эквивалентно, после предварительной обработки,
Это позволяет нам создавать макросы, чтобы мы могли писать код
И скрыть все уродливые проверки версий в определениях макросов.
Простой способ: Хедли
Теперь, когда вы понимаете механику того, как делать подобные вещи, сохраняя при этом чистый код, вы понимаете, что делает один из моих проектов, Хедли . Вместо того, чтобы копаться в тоннах документации и / или устанавливать столько версий компиляторов, сколько вы можете протестировать, вы можете просто включить Hedley (это единственный общедоступный заголовок C / C ++) и покончить с этим. Например:
Отключит предупреждение о вызове устаревшей функции в GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles и, возможно, других (возможно, я не буду обновлять этот ответ, когда обновляю Хедли). И на компиляторах, которые, как известно, не работают, макросы будут предварительно обработаны, и ваш код продолжит работать с любым компилятором. Конечно,
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
это не единственное предупреждение, о котором знает Хедли, и не отключение предупреждений, которые может сделать Хедли, но, надеюсь, вы поняли идею.источник
Вместо того, чтобы заглушать предупреждения, стиль gcc обычно использует либо стандартные конструкции C, либо
__attribute__
расширение, чтобы сообщить компилятору больше о вашем намерении. Например, предупреждение о назначении, используемом в качестве условия, подавляется путем помещения назначения в круглые скобки, то естьif ((p=malloc(cnt)))
вместоif (p=malloc(cnt))
. Предупреждения о неиспользуемых аргументах функции могут быть подавлены каким-то странным, который__attribute__
я никогда не смогу запомнить, или самовозвратом и т. Д. Но обычно я предпочитаю просто глобально отключить любую опцию предупреждения, которая генерирует предупреждения для вещей, которые будут происходить в правильном коде.источник
if ((p=malloc(cnt)) != NULL) ...
, что именно это и делает закулисный компилятор.Для тех, кто нашел эту страницу, ищет способ сделать это в IAR, попробуйте это:
См. Http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html для справки.
источник