Я знаю, що питання стосується GCC, але для людей, які шукають, як це зробити в інших та / або декількох компіляторах ...
TL; DR
Ви можете поглянути на Хедлі , який є єдиним заголовком C / C ++ у відкритому доступі, про який я писав, який робить для вас багато цього. Я покладу короткий розділ про те, як використовувати Хедлі для всього цього в кінці цієї публікації.
Вимкнення попередження
#pragma warning (disable: …)
має еквіваленти у більшості компіляторів:
- MSVC:
#pragma warning(disable:4996)
- GCC:
#pragma GCC diagnostic ignored "-W…"
де еліпсис - це назва попередження; наприклад , #pragma GCC diagnostic ignored "-Wdeprecated-declarations
.
- брязкіт:
#pragma clang diagnostic ignored "-W…"
. Синтаксис в основному такий же, як і GCC, і багато імен попередження однакові (хоча багато - ні).
- Компілятор Intel C: Використовуйте синтаксис MSVC, але майте на увазі, що номери попередження абсолютно різні. Приклад:
#pragma warning(disable:1478 1786)
.
- PGI: Є
diag_suppress
прагма:#pragma diag_suppress 1215,1444
- TI: Є
diag_suppress
прагма з тим же синтаксисом (але різними попереджувальними номерами!) Як PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (suncc): є
error_messages
прагма. Прикро, попередження різні для компіляторів C і C ++. Обидва вони відключають в основному однакові попередження:
- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C ++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- IAR: також використовує
diag_suppress
як PGI і TI, але синтаксис інший. Деякі з попереджувальних номерів однакові, але в інших я розходився:#pragma diag_suppress=Pe1444,Pe1215
- Гранули C: схожі на MSVC, хоча цифри знову різні
#pragma warn(disable:2241)
Для більшості компіляторів часто корисно перевірити версію компілятора, перш ніж намагатися її відключити, інакше ви просто в кінці запустите інше попередження. Наприклад, GCC 7 додала підтримку -Wimplicit-fallthrough
попередження, тож якщо ви переймаєтесь GCC до 7, вам слід зробити щось подібне
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Для clang та компіляторів на основі clang, таких як новіші версії XL C / C ++ та armclang, ви можете перевірити, чи знає компілятор про певне попередження за допомогою __has_warning()
макросу.
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Звичайно, ви також повинні перевірити, чи __has_warning()
існує макрос:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
Можливо, ви спокуситесь зробити щось на кшталт
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
Таким чином, ви можете використовувати __has_warning
трохи легше. Кланг навіть пропонує щось подібне для __has_builtin()
макросу у своєму посібнику. Не робіть цього . Інший код може перевірити __has_warning
і повернутися до перевірки версій компілятора, якщо він не існує, і якщо ви визначите, __has_warning
ви порушите їх код. Правильний спосіб зробити це - створити макрос у вашому просторі імен. Наприклад:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Тоді ви можете робити такі речі
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Натискання та вискакування
Багато компіляторів також підтримують спосіб виштовхування та виведення попереджень на стек. Наприклад, це вимкне попередження про GCC для одного рядка коду, а потім поверне його до попереднього стану:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Звичайно, між компіляторами немає сильної згоди щодо синтаксису:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- кланг:
#pragma clang diagnostic push
/#pragma diagnostic pop
- Intel 13+ (і, можливо, раніше):
#pragma warning(push)
/#pragma warning(pop)
- MSVC 15+ (VS 9.0 / 2008):
#pragma warning(push)
/#pragma warning(pop)
- ARM 5.6+:
#pragma push
/#pragma pop
- TI 8.1+:
#pragma diag_push
/#pragma diag_pop
- Pelles C 2.90+ (і, можливо, раніше):
#pragma warning(push)
/#pragma warning(pop)
Якщо пам'ять слугує, для деяких дуже старих версій GCC (наприклад, 3.x, IIRC) прагми push / pop повинні бути поза функцією.
Приховування горілих деталей
Для більшості компіляторів можливо приховати логіку використання макросів _Pragma
, що була представлена в C99. Навіть у режимі без C99 більшість компіляторів підтримують _Pragma
; великий виняток - MSVC, який має власне __pragma
ключове слово з іншим синтаксисом. Стандарт _Pragma
займає рядок, версія Microsoft не:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Приблизно рівноцінна, попередньо оброблена
#pragma foo
Це дозволяє нам створювати макроси, щоб ми могли писати подібний код
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
І приховати всі потворні перевірки версій у макрозначеннях.
Простий спосіб: Хедлі
Тепер, коли ви розумієте механіку того, як робити такі речі на портативному рівні, зберігаючи код чистим, ви розумієте, чим займається один із моїх проектів, Хедлі . Замість того, щоб переглядати тонни документації та / або встановлювати стільки версій стільки компіляторів, скільки ви можете протестувати, ви можете просто включити Hedley (це єдиний загальнодоступний заголовок C / C ++) і зробити це з ним. Наприклад:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
Відключить попередження про виклик застарілої функції на GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles та, можливо, інших (я, мабуть, не буду заважати оновлювати цю відповідь, коли я оновлюю Hedley). І на компіляторах, які, як відомо, не працюють, макроси будуть попередньо оброблені ні до чого, тому ваш код продовжить працювати з будь-яким компілятором. Звичайно, HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
це не єдине попередження, про яке знає Хедлі, і не відключення попереджень, про які може зробити Хедлі, але, сподіваємось, ви зрозумієте цю ідею.