如何使用另一个宏创建C宏名称?

时间:2017-08-08 00:26:49

标签: c macros c-preprocessor

我获得了一个定义以下宏的库:

#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 个答案:

答案 0 :(得分: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
}