2013-07-23 66 views
4

宏“VER”在其他我无法更改的头文件中定义为“((u_long)1)”。如何使用c宏生成函数名称

在我的代码中,我需要使用“test”和VER编写函数“test_1”。 但编译器报告错误,因为它是“test _((u_long)1)”而不是“test_1”生成的。

我的问题是:如何编写宏以便它可以生成“test_1”?

在此先感谢!

#define VER ((u_long)1)  /* This is defined in some other header file which I can't change*/ 

#define paste(x, y, z) x ## y ## z 
#define paste2(x, y, z) paste(x, y, z) 
#define fcall(fname) paste2(fname, _, VER) 

int test_1() { 
    return 0; 
} 

int main() { 
    fcall(test)(); 
    return 0; 
} 

回答

5

我不能保证它是100%可移植的,但它应该工作:

#define VER ((u_long)1) 

#define STRIP1(x) STRIP2 x 

#define STRIP2(x) STRIP3 x 

#define STRIP3(x) 

#define paste(x, y, z) x ## y ## z 
#define paste2(x, y, z) paste(x, y, z) 
#define fcall(fname) paste2(fname, _, STRIP1(VER)) 

Live example

它通过解释的VER定义为宏调用里面的括号内。这里的个体扩展,因为它们发生:

STRIP1(VER) // STRIP1 with argument VER 

STRIP2 ((u_long)1) // STRIP2 with argument (u_long)1 

STRIP3 (u_long)1 // STRIP3 with argument u_long, followed by 1 

1 

如果我们重新安排的空白(这是微不足道反正),我们得到这样的:

STRIP1(VER) 

STRIP2((u_long) 1) 

STRIP3(u_long) 1 

1 
+0

这个怎么用? –

+0

@brianbeuning我已经添加了解释。 – Angew

+0

这非常酷。但是如果有人改变了VER的定义(比如说(1)),它就会中断。 –

0

与该源,你可能无法,因为宏展开是文本,所以((u_long)1)不可能成为1

一个解决方案当然是实际编写一些代码来打印VER的实际值。另一种方法是说服自己该文件的人,你不能改变,他们应该改变它你...

0

改性Angew版本

#define VER ((u_long)1) 

#define _(x) x 
#define id(x) _(x) 

#define STRIP3(x) 
#define STRIP2(x) id(STRIP3 x) 
#define STRIP1(x) id(STRIP2 x) 

#define paste(x, y, z) x ## y ## z 
#define paste2(x, y, z) paste(x, y, z) 
#define fcall(fname) paste2(fname, _, STRIP1(VER))