Вибірково вимкнути попередження GCC лише для частини одиниці перекладу?


85

Який найближчий GCC еквівалентний цьому коду препроцесора MSVC?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

Ми маємо код у загальновключених заголовках, і ми не хочемо генерувати конкретне попередження. Однак ми хочемо, щоб файли, які містять ці заголовки, продовжували генерувати це попередження (якщо в проекті це попередження увімкнено).


Якщо заголовки встановлені в / usr / include або те, що у вас є, gcc за замовчуванням не створює для них попереджень.
Spudd86

Відповіді:


95

Це можливо в GCC, починаючи з версії 4.6 або приблизно в червні 2010 р.

Ось приклад:

#pragma GCC diagnostic push
#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 */

8
Функція push and pop була додана у gcc 4.6 ( gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html ).
Дейв Йогансен

Можливо, вам захочеться натиснути двічі, якщо ви збираєтеся двічі вискочити.
Ден,

2
@Dan: Прочитайте керівництво та коментуйте. Зверніть увагу на походження прикладу.
Matt Joiner

FYI для старих версій, таких як 4.4.7, ви все ще можете використовувати, #pragma GCC diagnostic [error|warning|ignored]але popне реалізовано / не підтримується.
Тревор Бойд Сміт,

36

Найближче є діагностичним Прагма GCC , #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". Це не дуже близько до того, що ви хочете, і див. Посилання для деталей та застережень.


1
Ви знаєте, що і де може бути обґрунтуванням відмови від додавання цієї функції? (Не вдалося знайти.) Я вважаю попередження push-disable-pop корисним.

1
Я насправді не уявляю, що "не додавання функцій" до gcc, як правило, має обґрунтування настільки, наскільки відсутність будь-кого, хто подає робочий патч.
хаос

14
Справа не в тому, що ніхто не готовий виконувати роботу щодо такого роду дрібнодисперсного попереджувального контролю в gcc або подавати код - я знаю одну велику корпорацію Силіконової долини, яка вже це робила, а іншу, яка була б рада комусь заплатити зробити це і отримати код у потік. Швидше, під час обговорення з хлопцем, який (як один із тих, хто підтримує gdb), підключений до цього, у підтриманих gcc є філософія: "Якщо є попередження, це помилка, і вам потрібно це виправити". Отже (imo) це релігійний аргумент, і вони контролюють код, щоб перемогти.
Bob Murphy

Щоб додати коментар Боба, розробники GCC вже не любили #pragmaдирективу, тому все, що стосується GCC, швидше за все, буде реалізовано як __attribute__((foo)).
Том

10
новий gcc (> = 4,4), #pragma GCC push_optionsтак що ви можете займатися
Spudd86

33

Я зробив щось подібне. Щодо стороннього коду, я взагалі не хотів бачити жодних попереджень. Отже, замість уточнення -I/path/to/libfoo/include, я використав -isystem /path/to/libfoo/include. Це змушує компілятор розглядати ці файли заголовків як "системні заголовки" з метою попереджень, і поки ви не вмикаєте -Wsystem-headers, ви в основному в безпеці. Я все ще бачив, як звідти витікає кілька попереджень, але це скорочує більшу частину сміття.

Зауважте, що це допомагає вам лише в тому випадку, якщо ви можете ізолювати код, що порушує, за допомогою каталогів include. Якщо це просто підмножина вашого власного проекту або змішана з іншим кодом, вам не пощастило.


1
Чудова порада. Якщо ви використовуєте LLVM, додайте прапорець -isystem у розділі "Інші прапори C" у розділі "Apple LLVM Compiler - Language".
Нестор

@Tom Дякую за обмін. Я не можу зрозуміти, де використовувати ваше рішення. Ви можете сказати трохи більше?
Lorenzo B

1

Це розширення відповіді Метта Джойнара .

Якщо ви не хочете породжувати прагми по всьому коду, ви можете використовувати оператор _Pragma :

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.