Ignoring "-Wc99-extensions" diagnostic warning

Compiling some code I am receiving the warning:

"warning: empty macro arguments are a C99 feature [-Wc99-extensions]"

The warning is output for file A, line V during a macro invocation.

But the actual macro using an empty argument is in file B, line W. If I surround file B, line W with:

# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wc99-extensions"

// line W, macro definition with empty macro argument

# pragma clang diagnostic pop

the warning still occurs. Is this a clang bug ?

I have noticed that if I get a warning about using variadic macros ( "-Wvariadic-macros" ) if I surround the actual variadic macro with:

# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wvariadic-macros"

// variadic macro definition

# pragma clang diagnostic pop

the warning goes away.

For various reasons too lengthy to explain, std=c99 or std=c++0x or std=c++11 are not specified but I still need to eliminate the "-Wc99-extensions" warning in the actual source file.

Can you provide a reduced test case for this? What is on the line A:V?

Can you provide a reduced test case for this?

Very difficult with the actual situation since this is Boost, which tends to get complicated quickly. I will try to produce a manufactured situation which shows this problem, and then post it.

What is on the line A:V?

BOOST_MPL_AUX_NA_SPEC(3, if_)

There is no empty macro argument here. But much further down in the macro stack trace which clang output shows at B:W is:

#define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,)

with a little caret showing the empty argument. So when I surround that line at B:W with the appropriate #pragma it does not turn off the warning. No doubt if I surround A:V with the appropriate #pragma it may well turn off the warning, but that is a ridiculous way to solve the problem. Some other macro path may eventually invoke B:W and then the problem will re-occur etc. etc.

Can you provide a reduced test case for this?

Very difficult with the actual situation since this is Boost, which tends
to get complicated quickly. I will try to produce a manufactured situation
which shows this problem, and then post it.

What is on the line A:V?

BOOST_MPL_AUX_NA_SPEC(3, if_)

There is no empty macro argument here. But much further down in the macro
stack trace which clang output shows at B:W is:

#define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_,
n)(__VA_ARGS__,)

with a little caret showing the empty argument. So when I surround that
line at B:W with the appropriate #pragma it does not turn off the warning.
No doubt if I surround A:V with the appropriate #pragma it may well turn
off the warning, but that is a ridiculous way to solve the problem. Some
other macro path may eventually invoke B:W and then the problem will
re-occur etc. etc.

OK, I see. We use the diagnostic state at the expansion location (that is,
where the outermost macro expansion occurs, or more generally, the point in
the *preprocessed* token stream where the issue occurs) to determine
whether to enable the diagnostic, and there are some good reasons why we
pick that point to perform the check. We could change that for this
particular diagnostic, but the simplest approach would seem to be to make
Boost disable the diagnostic at the right place in the token stream:

#if defined(__clang__)
#define BOOST_SUPPRESS_EMPTY_MACRO_ARG_PUSH() _Pragma("clang diagnostic
push") _Pragma("clang diagnostic ignored \"-Wc99-extensions\"")
#define BOOST_SUPPRESS_EMPTY_MACRO_ARG_POP() _Pragma("clang diagnostic pop")
#else
// ...
#endif

#define BOOST_PP_VARIADIC_ELEM(n, ...) \
  BOOST_SUPPRESS_EMPTY_MACRO_ARG_PUSH() \
  BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,) \
  BOOST_SUPPRESS_EMPTY_MACRO_ARG_POP()