定义宏中的实用主义

是否有某种方法可以将语用语句与其他语句一起嵌入宏中?

我试图达到这样的效果:

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

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

50186 次浏览

是否有某种方法可以将语用语句与其他语句一起嵌入宏中?

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

不,没有便携式的方法可以做到这一点。然而,根本就没有使用 # 杂注的可移植方法。正因为如此,许多 C/C + + 编译器定义了自己的方法来执行类似于杂注的操作,而且它们通常可以嵌入到宏中,但是您需要在每个编译器上使用不同的宏定义。如果你愿意走这条路,你最终往往会做这样的事情:

#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)。使用括号结构允许您定义一些始终有效的东西,即使您必须将整个类型签名传递给编译器结构。

当然,如果您尝试在没有所需属性的情况下将其移植到编译器,那么除了让宏保持不扩展之外别无他法,只能希望代码仍然可以运行。在纯粹的警告或优化杂注的情况下,这是可能的。在其他情况下,就没那么好了。

对了,我怀疑您实际上需要将弱 _ b 和弱 _ e 定义为带有参数的宏,但是我不愿意为了这个示例而阅读文档,以了解如何创建弱定义。我把它留给读者作为练习。

如果您正在使用 c99或 c + + 0x,那么有一个杂注操作符,用作

_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
;

使用 _ Pragma (“参数”)可以做的一件好事是使用它处理一些编译器问题,例如

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif