2017-08-08 92 views
0

我一直在考虑定义以下宏库:如何使用另一个宏创建C宏名称?

#define FOO_0(A, B) (A + B) 
#define FOO_1(A, B) (A - B) 

现在我想创建一个新的宏MY_FOO,需要一个第三个参数x,并用它构建宏的名字叫(如FOO_<x>

这里是我的实验:

#define MY_FOO(X, A, B) FOO_## X ##(A, B) 

然而,当我尝试在我的代码使用它:

int main(void) { 
    int a = 2, b = 3, x = 0; 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
    return 0; 
} 

我得到以下错误:

prog.c: In function ‘main’: 
prog.c:6:25: error: pasting "FOO_x" and "(" does not give a valid preprocessing token 
#define MY_FOO(X, A, B) FOO_## X ##(A, B) 
         ^
prog.c:11:41: note: in expansion of macro ‘MY_FOO’ 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
             ^~~~~~ 
prog.c:6:25: warning: implicit declaration of function ‘FOO_x’ [-Wimplicit-function-declaration] 
#define MY_FOO(X, A, B) FOO_## X ##(A, B) 
         ^
prog.c:11:41: note: in expansion of macro ‘MY_FOO’ 
    printf("FOO_%d(%d, %d) = %d", x, a, b, MY_FOO(x, a, b)); 
             ^~~~~~ 

有没有办法来解决这个?

+1

第二个##不是必需的。 –

+1

在C中,永远不需要创建具有完全变量名称的宏。宏名称是为程序员而不是程序。如果你仍然想出这样的需求,你应该运行一个生成C代码的外部脚本。 – Lundin

+0

在下面的帖子中自动生成@bipll提出的代码实际上可能是一个非常好的主意,因为我必须对很多宏使用相同的模式 – Muffo

回答

3

如果你真的需要把运行时间值到宏名,你必须做你自己:

switch(x) { 
    case 0: printf("FOO_0(%d, %d) = %d", a, b, FOO_0(a, b)); 
      break; 
} 

你甚至可以让它稍微当地语法DEFS先进:

switch(x) { 
#define CASE(x) case x: printf("FOO_" #x "(%d, %d) = %d", a, b, FOO_ ## x(a, b)); \ 
         break 
    CASE(0); 
#undef CASE 
} 
+0

感谢您的答案!运行时间和编译时间值之间的区别可能是这个问题的关键。 – Muffo

+1

除此之外,宏在编译本身之前是解析时间值。 :) – bipll