如何在Clang中定义具有多个pragma的宏?

22

我想添加一些宏来方便(取消)设置我们正在内部弃用的例程周围的特定警告。

我想把这个变成:

#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个回答

24
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的设置变得相关。
如果您真的只想在设置了MY_DEPRECATED的情况下使Foo过时,那么正确的方法是
#ifdef MY_DEPRECATED
 #define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#else
 #define ATTRIBUTE_DEPRECATED
#endif

void Foo() ATTRIBUTE_DEPRECATED;

节省了我大量时间。谢谢! - tonymontana

10

你可以使用这个解决方案:

#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();
                      );

如果 expr 包含逗号,那么这种方法行不通。你可以使用可变参数宏(C++11 或更高版本)来避免这个问题。 - Daira Hopwood

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