如何为Clang定义具有多个编译指示的宏?

时间:2012-12-11 19:01:30

标签: macros clang pragma

我想添加一些宏来缓解(取消)在我们内部弃用的例程中设置特定警告。

我想转此:

#pragma clang diagnostic push
#pragma clang diagnostic warning "-Wdeprecated-declarations"

void Foo() __attribute__((deprecated("Warning: deprecated routine")))

#pragma clang diagnostic pop

进入这个:

MY_DEPRECATED_BEGIN

void Foo() MY_DEPRECATED

MY_DEPRECATED_END

MY_DEPRECATED_BEGIN宏给了我麻烦,因为我必须在一个宏中指定两个 pragma。可以这样做吗?

(仅使用MY_DEPRECATED宏实现相同效果的解决方案的奖励积分!)

2 个答案:

答案 0 :(得分:17)

void Foo() __attribute__((deprecated));

#define MY_DEPRECATED_BEGIN \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic warning \"-Wdeprecated-declarations\"")


int main()
{
MY_DEPRECATED_BEGIN
    Foo();
#pragma clang diagnostic pop
}

对您的技术问题的简短回答是C99提供_Pragma("foo")构造,该构造等同于#pragma foo,但稍后会稍后处理,并且不需要单独处理。

你的另一个问题是-Wdeprecated-declarations没有按照你的想法行事。只是声明一个已弃用的函数永远不会给你一个诊断,因为__attribute__((deprecated)) 假设要使用(通常在头文件中)。导致诊断的原因是,如果您使用已弃用的功能 - 并且 指出-Wdeprecated的设置变得相关。

如果你真的只想弃用Foo iff MY_DEPRECATED,那么正确的方法

#ifdef MY_DEPRECATED
 #define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#else
 #define ATTRIBUTE_DEPRECATED
#endif

void Foo() ATTRIBUTE_DEPRECATED;

答案 1 :(得分:7)

您可以使用此解决方案:

#define NS_SUPPRESS_DIRECT_USE(expr)   _Pragma("clang diagnostic push") \
                                       _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")\
                                       expr\
                                       _Pragma("clang diagnostic pop") 

然后添加它:

NS_SUPPRESS_DIRECT_USE(
                      Foo();
                      );