定义宏中的语法


99

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

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

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

如果存在的话,我可以使用增强解决方案(节省波动)。


5
可以说两者都不是-C或C ++标准都没有定义#pragmas。

即使不是他想要运行的特定允许的子命令,预处理器也是。
小狗

@DeadMG:C和C ++之间有很多共同点。尽管预处理是常见的方法,但根据使用哪种语言标准(C89,C99,C ++和C ++ 0x FCD),在如何指定预处理方面存在重大差异。
James McNellis

2
@James McNellis:仅仅因为从技术上讲,大多数C程序都可移植到C ++,但并没有实现真正的通用功能,因为没有C ++程序员会做绝大多数。两种语言实际上并没有太多共同之处。
小狗

Answers:


114

如果您使用的是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
 ;

32
仅供参考:MSVC具有__pragma()预处理器运算符,不幸的是,该运算符与C99的_Pragma()运算符略有不同(C99带有字符串文字,MSVC带有不在字符串中的令牌):msdn.microsoft.com/zh-cn/library/d9x1s805 .aspx
Michael Burr 2010年

15
@MichaelBurr MSVC总是必须有所不同,不是吗?
托马斯

5

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

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

0

不,没有可移植的方法。再说一次,根本没有使用#pragma的可移植方式。因此,许多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以来已经有好几年了。使用括号结构可以使您定义始终有效的内容,即使您必须将整个类型签名传递给编译器构造。

当然,如果尝试在没有所需属性的情况下将其移植到编译器,则您无能为力,只能将宏扩展为空,并希望您的代码仍然运行。在纯粹警告或优化实用程序的情况下,这是可能的。在其他情况下,不是很多。

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


-3

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

不可以,您不能将预处理程序语句放入预处理程序语句中。但是,您可以将其放入inline函数中。但是,这失败了C


1
将其放入内联函数有什么好处?在可以识别功能的所有内容之前处理预处理程序指令。

2
C99具有inline,大多数主要的C89实现都有一些变化。
克里斯·卢茨

@Chris假设您的评论针对我-您的意思是-什么?

@Neil-不,对不起。我将其指向@sbi的最后一句话。
克里斯·卢茨

1
@Chris:啊,inlineC又是从C ++借来的!:)
2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.