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?
Clang was intended to reduce debug time by giving proper error messages, better IDE integration etc. Of course, it has grown to support more languages than gcc and it's integration with llvm has popularized it.
Release Clang VersionsClang is also provided in all major BSD or GNU/Linux distributions as part of their respective packaging systems. From Xcode 4.2, Clang is the default compiler for Mac OS X.
The Microsoft C++ Standard Library requires at least Clang 8.0. 0. Later versions of Visual Studio provide newer versions of the Clang toolset. The bundled version of Clang gets updated automatically to stay current with updates in the Microsoft implementation of the Standard Library.
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)
If you have this kind of problem with a 3d party pod, you may find this useful
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexpansion-to-defined"
#import <pop/POP.h>
#pragma clang diagnostic pop
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With