Walter Walter - 4 years ago 592
C Question

How to deal with clang's (3.9) -Wexpansion-to-defined warning?

clang 3.9 has added to

-Wall
a the warning
-Wexpansion-to-defined
, which produces


macro expansion producing 'defined' has undefined behaviour


in case
defined
is used outside an
#if
expression, including the case of a macro that is then used within an
#if
expression. For example the following code

// in some file:
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))

// possibly in another file:
#if defined(__clang__) || HAS_GNU
/* ... */
#endif


produces

test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
#if defined(__clang__) || HAS_GNU
^
test.cc:3:18: note: expanded from macro 'HAS_GNU'
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))
^
test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
test.cc:3:40: note: expanded from macro 'HAS_GNU'
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))


So what's the 'correct' way to do that?

Answer Source

You can use #if - #else macros:

#if defined(__GNUC__) && !defined(__clang__)
#define HAS_GNU 1
#else
#define HAS_GNU 0
#endif

Or, if you're willing to change the code that uses HAS_GNU, perhaps more conventional way:

#if defined(__GNUC__) && !defined(__clang__)
#define HAS_GNU
#endif

#if defined(__clang__) || defined(HAS_GNU)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download