【问题标题】:How to create C macro name using another macro?如何使用另一个宏创建 C 宏名称?
【发布时间】:2017-08-08 00:26:48
【问题描述】:

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

#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));
                                         ^~~~~~

有没有办法解决这个问题?

【问题讨论】:

  • 第二个## 不是必需的。
  • 在 C 中,永远不需要创建具有完全变量名的宏。宏名是给程序员的,不是给程序的。如果你仍然有这样的需求,你应该运行一个生成 C 代码的外部脚本。
  • 自动生成@bipll 在下面的帖子中提出的代码实际上可能是一个非常好的主意,因为我必须对很多宏使用相同的模式

标签: c macros c-preprocessor


【解决方案1】:

如果您确实需要将运行时值转换为宏名称,则必须自己完成:

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

您甚至可以使用本地语法定义使其更高级:

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

【讨论】:

  • 感谢您的回答!运行时值和编译时值的区别可能是这个问题的关键。
  • 更重要的是,宏在编译之前是解析时值。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多