-Wundef не игнорируется с прагмой в g++

Учитывая следующий код:

#if MACRO_WITHOUT_A_VALUE
int var;
#endif

int main(){}

Когда скомпилировано, g++ -std=c++1z -Wundef -o main main.cpp,
выдает следующее предупреждение:

main.cpp:1:5: warning: "MACRO_WITHOUT_A_VALUE" is not defined [-Wundef]
 #if MACRO_WITHOUT_A_VALUE
     ^

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

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic push
#endif

#if MACRO_WITHOUT_A_VALUE
int var;
#endif

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif

int main(){}

Это только решает проблему в clang++,

Команда clang++ -std=c++1z -Wundef -o main main.cpp строит без предупреждений.
Команда g++ -std=c++1z -Wundef -o main main.cpp строит с тем же [-Wundef] предупреждение как раньше.

Как я могу подавить -Wundef предупреждения в g++ ?

g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0
clang version 3.8.0

1 ответ

Решение

То, что я делал раньше, когда сторонние заголовки вызывали предупреждения, заключалось в том, чтобы обернуть их в свой собственный частный заголовок, который использует #pragma GCC system_header просто заставить замолчать все предупреждения из этого заголовка. Я использую свою собственную обертку, чтобы сохранить аккуратность включений и предусмотреть дополнительную точку настройки в будущем, если это необходимо.

Это не отключение предупреждения, а исправление кода препроцессора, чтобы избежать его. Приведенные ниже тесты основаны на аналогичной проблеме здесь, используя clang -Weverything...

#define ZERO 0
#define ONE 1
#define EMPTY

// warning: 'NOTDEFINED' is not defined, evaluates to 0 [-Wundef]
#if NOTDEFINED
#warning NOTDEFINED
#endif

// false
#if ZERO
#warning ZERO
#endif

// true
#if ONE
#warning ONE
#endif

// error: expected value in expression
#if EMPTY
#warning EMPTY
#endif

// false
#if defined(NOTDEFINED) && NOTDEFINED
#warning NOTDEFINED
#endif

// false
#if defined(ZERO) && ZERO
#warning ZERO
#endif

// true
#if defined(ONE) && ONE
#warning ONE
#endif

// error: expected value in expression
#if defined(EMPTY) && EMPTY
#warning EMPTY
#endif

Один лайнер #if defined(SOME_MACRO) && SOME_MACRO можно избежать этого предупреждения. Чтобы явно обработать дело...

#if defined(DEBUG_PRINT)
#if DEBUG_PRINT
... true
#else
... false
#endif
#else
#error DEBUG_PRINT must be defined
#endif

Обрабатывать EMPTY см. это: Как проверить, является ли символ препроцессора #define'd, но не имеет значения?

Другие вопросы по тегам