7

Given the following code:

#if MACRO_WITHOUT_A_VALUE
int var;
#endif

int main(){}

When compiled with, g++ -std=c++1z -Wundef -o main main.cpp,
it produces the following warning:

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

I'd like to keep the warning flag enabled, but suppress this particular instance.
I apply the following:

#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(){}

This only solves the problem in clang++.

The command clang++ -std=c++1z -Wundef -o main main.cpp builds without warnings.
The command g++ -std=c++1z -Wundef -o main main.cpp builds with the same [-Wundef] warning as before.

How can I suppress -Wundef warnings in g++?

g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0
clang version 3.8.0
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • 1
    Can you use `#if defined(MACRO_WITHOUT_A_VALUE) && MACRO_WITHOUT_A_VALUE`? – Ry- Aug 08 '16 at 13:57
  • Perhaps, but I'm wrapping 3rd party code that I'd rather not modify. – Trevor Hickey Aug 08 '16 at 13:58
  • Wrap it in `#ifdef` instead then? – Ry- Aug 08 '16 at 13:59
  • @Ryan That's what I'm doing right now. I was hoping I could have some kind of catch all without having to know the internal macros. Something like: `#include "push_all_warnings.hpp" #include "3rd_party.hpp" #include "pop_all_warnings.hpp"` – Trevor Hickey Aug 08 '16 at 14:01
  • You have the `ignored` and `push` directives backwards, but it's otherwise a known GCC problem. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 – Ry- Aug 08 '16 at 14:17
  • I can't tell from your question and the comments if this is for one specific instance or an entire third party header. If the former, wrap in `#ifdef`, in the latter case what I've done before is create my own `wrap_
    .hpp` file that uses `#pragma GCC system_header` and then includes the third party header that induces warnings.
    – Mark B Aug 08 '16 at 15:36
  • @MarkB That's exactly what I'm looking for. `system_header` will work much better than me attempting to suppress every warning before including the 3rd party header. – Trevor Hickey Aug 08 '16 at 15:43

2 Answers2

7

What I've done before when third party headers were inducing warnings was to wrap them in my own private header that uses #pragma GCC system_header to just silence all the warnings from that header. I use my own wrapper to keep the includes neat and allow for an additional customization point in the future if needed.

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

This isn't disabling the warning, but fixing the preprocessor code to avoid it. The below tests are based on a similar issue here, using 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

The one liner #if defined(SOME_MACRO) && SOME_MACRO can avoid this warning. To explicitly handle the case...

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

To handle EMPTY see this: How to test if preprocessor symbol is #define'd but has no value?

jozxyqk
  • 16,424
  • 12
  • 91
  • 180