2010-06-12 101 views
0

我工作的一个项目,我有这样的代码如下:GCC预处理器内联函数名

#define NAME() Array 

inline NAME()* NAME()_init (void* arg0){return (NAME()*)Object_init(arg0);} 

但我得到以下结果:

inline Array* Array _init (void* arg0){return (Array*)Object_init(arg0);} 

随着之间的空间“数组”和“_init”因为这是一个函数名,所以我显然不想要这个空间。有谁知道如何获得空间?

回答

1

你应该改变语义是这样的:

#define NAME(X) Array##X 
inline NAME()* NAME(_init) (void* arg0){return (NAME()*)Object_init(arg0);}

编辑:至少它与GNU CPP。

EDIT2:与-ansi -pedantic也试过,似乎没有任何警告的工作...

+0

它可能是,但OP指定GNU预处理器,并我已经测试过它 – ShinTakezou 2010-06-12 17:26:49

+0

对不起,我的错。 C99增加了对空参数的支持。 – 2010-06-12 17:40:58

2

的唯一途径两个标记合并成一个(例如,调用NAME()_init的结果结合)是使用连接运算符(##)。您需要这样做:

#define REAL_CONCATENATE(x, y) x ## y 
#define CONCATENATE(x, y) REAL_CONCATENATE(x, y) 

#define NAME() Array 
inline NAME()* CONCATENATE(NAME(), _init) (void* arg0){return (NAME()*)Object_init(arg0);} 

是的,the extra level of indirection is necessary

注意,你并不需要,如果你不带任何参数使用函数宏,所以你可以很容易地使用:

#define NAME Array 
inline NAME* CONCATENATE(NAME, _init) (void* arg0){return (NAME*)Object_init(arg0);} 
+0

它被称为令牌粘贴,而不是串联 - 字符串连接发生在标记之后,粘贴之前,并且不需要任何操作符。 – 2010-06-12 17:37:50

+0

@Pete:C和C++语言标准都使用_concatenate; _这并不意味着_token concatenation_与_string literal concatenation_(或者任何其他形式的连接,就此而言)是相同的。 – 2010-06-12 17:40:10