111

有没有办法将 pragma 语句与其他语句一起嵌入到宏中?

我正在尝试实现以下目标:

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

如果存在提升解决方案(除了波浪),我可以接受。

4

4 回答 4

127

如果您使用的是 c99 或 c++0x,则有 pragma 运算符,用作

_Pragma("argument")

这相当于

#pragma argument

除了它可以在宏中使用(参见 c99 标准的第 6.10.9 节,或 c++0x 最终委员会草案的第 16.9 节)

例如,

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

当放入gcc -E

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;
于 2010-06-12T22:22:28.407 回答
5

使用 _Pragma("argument") 可以做的一件好事是用它来处理一些编译器问题,例如

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif
于 2012-02-28T15:34:32.760 回答
0

不,没有便携的方法可以做到这一点。再说一次,根本没有可移植的方式来使用#pragma。正因为如此,许多 C/C++ 编译器定义了自己的方法来执行类似 pragma 的事情,并且它们通常可以嵌入到宏中,但是每个编译器都需要不同的宏定义。如果你愿意走这条路,你通常会做这样的事情:

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

万一它不明显你想定义Weak_bWeak_e作为开始和结束括号结构,因为像 GCC 这样的一些编译器将属性作为类型签名的附录添加,而像 MSC 这样的一些编译器将它作为前缀添加(或者至少它做了一次,自从我使用 MSC 以来已经有好几年了)。即使您必须将整个类型签名传递给编译器构造,使用括号结构也可以定义始终有效的东西。

当然,如果您尝试将其移植到没有您想要的属性的编译器,那么您无能为力,只能将宏扩展为空,并希望您的代码仍然可以运行。在纯粹警告或优化编译指示的情况下,这很可能。在其他情况下,没有那么多。

哦,我怀疑您实际上需要将 Weak_b 和 Weak_e 定义为带有参数的宏,但我不愿意通读文档以了解如何仅为此示例创建弱定义。我把它留给读者作为练习。

于 2010-06-12T22:12:59.493 回答
-3

有什么方法可以将 pragma 语句与其他语句一起嵌入到宏中?

不,您不能将预处理器语句放入预处理器语句中。但是,您可以将其放入inline函数中。但是,这会破坏C标签。

于 2010-06-12T21:32:56.730 回答