Выборочно отключить предупреждения GCC только для части единицы перевода?

Какой 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.

У нас есть код в часто включенных заголовках, который мы не хотим генерировать конкретное предупреждение. Однако мы хотим, чтобы файлы, содержащие эти заголовки, продолжали генерировать это предупреждение (если в проекте включено это предупреждение).


person Jon-Eric    schedule 08.06.2009    source источник
comment
Если заголовки установлены в / usr / include или что у вас есть, gcc по умолчанию не генерирует для них предупреждения.   -  person Spudd86    schedule 15.06.2010


Ответы (4)


Это возможно в 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 */
person Matt Joiner    schedule 03.08.2010
comment
Функции push и pop были добавлены в gcc 4.6 (gcc .gnu.org / onlinedocs / gcc-4.6.0 / gcc / Diagnostic-Pragmas.html). - person Dave Johansen; 07.12.2011
comment
Вы, вероятно, захотите нажать дважды, если собираетесь лопнуть дважды. - person Dan; 20.03.2014
comment
@Dan: Прочтите руководство и прокомментируйте. Обратите внимание на происхождение примера. - person Matt Joiner; 23.03.2014
comment
К вашему сведению более старые версии, такие как 4.4.7 вы все еще можете использовать #pragma GCC diagnostic [error|warning|ignored], но pop не реализован / не поддерживается. - person Trevor Boyd Smith; 02.04.2018

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

person chaos    schedule 08.06.2009
comment
Знаете ли вы, что и где может быть основание для отказа от добавления этой функции? (Я не смог его найти.) Я считаю полезным предупреждение push-disable-pop. - person ; 17.11.2009
comment
Я действительно не думаю, что отказ от добавления функций в gcc имеет такое объяснение, как отсутствие кого-либо, отправляющего рабочий патч. - person chaos; 18.11.2009
comment
Дело не в том, что никто не желает выполнять работу для такого рода детализированного контроля предупреждений в gcc или отправлять код - я знаю одну крупную корпорацию Кремниевой долины, которая уже сделала это, а другая была бы рада заплатить кому-то чтобы сделать это и получить код в потоке. Скорее, согласно обсуждению с парнем, который (как один из сопровождающих gdb) подключился к этому материалу, у сопровождающих gcc есть философия: если есть предупреждение, это ошибка, и вам нужно ее исправить. Итак (имо) это религиозный аргумент, и они контролируют код, поэтому они выигрывают. - person Bob Murphy; 22.01.2010
comment
Чтобы добавить к комментарию Боба, разработчики GCC не любили директиву #pragma, поэтому все, что специфично для GCC, вероятно, будет реализовано как __attribute__((foo)). - person Tom; 24.01.2010
comment
в новом gcc (›= 4.4) есть #pragma GCC push_options, так что вы можете возиться не только с диагностикой ... gcc.gnu.org/onlinedocs/gcc/ - person Spudd86; 15.06.2010

Я сделал нечто подобное. Для стороннего кода я вообще не хотел видеть никаких предупреждений. Поэтому вместо того, чтобы указывать -I/path/to/libfoo/include, я использовал -isystem /path/to/libfoo/include. Это заставляет компилятор обрабатывать эти файлы заголовков как «системные заголовки» с целью предупреждений, и пока вы не включите -Wsystem-headers, вы в большей степени в безопасности. Я все еще видел, как оттуда утекает несколько предупреждений, но это сокращает большую часть мусора.

Обратите внимание, что это только поможет вам, если вы можете изолировать проблемный код с помощью include-directory. Если это просто подмножество вашего собственного проекта или смешанное с другим кодом, вам не повезло.

person Tom    schedule 22.01.2010
comment
Отличный совет. При использовании LLVM добавьте флаг -isystem в разделе «Другие флаги C» в разделе «Компилятор Apple LLVM - язык». - person Nestor; 14.03.2012
comment
@Tom Спасибо, что поделились. Я не могу понять, где использовать ваше решение. Вы можете сказать немного больше? - person Lorenzo B; 07.03.2013

Это расширение к ответу Мэтта Джойнера.

Если вы не хотите создавать прагмы по всему коду, вы можете использовать Оператор _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
person Cássio Renan    schedule 02.04.2018