如何处理clang(3.9)的-Wexpansion-to-defined警告?

19

clang 3.9增加了-Wall警告选项,其中包括-Wexpansion-to-defined警告选项,该选项会产生以下警告:

宏定义展开为“defined”的行为未定义

如果defined#if表达式之外被使用,包括将宏用于#if表达式的情况。例如,以下代码:

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

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

产生

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__))

那么,做这件事的“正确”方式是什么?

2个回答

36

您可以使用#if - #else宏:

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

或者,如果你愿意改变使用HAS_GNU的代码,也许更常规的方法:

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

#if defined(__clang__) || defined(HAS_GNU)

5
如果您遇到与第三方Pod相关的问题,您可能会发现这很有用。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexpansion-to-defined"
#import <pop/POP.h>
#pragma clang diagnostic pop

1
这并不回答问题。问题不是关于禁用警告。 - Jean-François Fabre
9
问题是“如何处理...”。如果你使用第三方库,显然不能更改源代码。那么如何处理这个警告呢?尤其是如果该项目将警告视为错误。 - ilnar_al

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接