【问题标题】:Use multiple macros in a macro definition在宏定义中使用多个宏
【发布时间】:2016-11-06 16:01:57
【问题描述】:

我正在尝试在另一个宏的定义中使用多个宏,但似乎无法将它们连接在一起。这是我正在尝试做的一个非常简化的版本:

#include <stdio.h>

#define PICK_SET_A

#ifdef PICK_SET_A
#define SET A
#endif
#ifdef PICK_SET_B
#define SET B
#endif

#define ENABLE_VAR_1_A   1
#define ENABLE_VAR_2_A   1

#define ENABLE_VAR_1_B   0
#define ENABLE_VAR_2_B   0

#define MACRO_RESOLVE(var,set) ENABLE_VAR_##var##_##set

#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
#define ENABLE_VAR_2     MACRO_RESOLVE(2, SET)

int main(int argc, char **argv) {

    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);

    return 0;
}

我希望结果是0

但是,我遇到了编译错误,因为 MACRO_RESOLVE 宏没有按照我期望的方式解析:

$ gcc -o asdf asdf.c
asdf.c:25:36: error: use of undeclared identifier 'ENABLE_VAR_1_SET'
    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);
                                   ^
asdf.c:20:26: note: expanded from macro 'ENABLE_VAR_1'
#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
                         ^
asdf.c:18:32: note: expanded from macro 'MACRO_RESOLVE'
#define MACRO_RESOLVE(var,set) ENABLE_VAR_##var##_##set
                               ^
<scratch space>:229:1: note: expanded from here
ENABLE_VAR_1_SET
^
1 error generated.

所以当我定义ENABLE_VAR_1 时,看起来SET 没有得到扩展。

【问题讨论】:

  • 我可以用其他解决方案来解决这个问题。主要目标是能够像这样将两个宏插入到另一个宏的定义中。
  • 你为什么要用宏来做这个?
  • @EdHeal 通过在宏中执行此操作,我可以尽可能避免函数调用和内存查找。当我完成它时,我会很高兴指向我的 GitHub PR,但简短的版本是有时我希望在编译时解决这个问题(使用所有这些宏),有时它必须在运行时解决.

标签: c c-preprocessor


【解决方案1】:

由于您正在尝试构建宏名称,因此您需要在此过程中进行足够的中间扩展,以使所有标记都扩展。见live here

#include <stdio.h>

#define PICK_SET_A

#ifdef PICK_SET_A
#define SET A
#endif
#ifdef PICK_SET_B
#define SET B
#endif

#define ENABLE_VAR_1_A   1
#define ENABLE_VAR_2_A   1

#define ENABLE_VAR_1_B   0
#define ENABLE_VAR_2_B   0

#define MACRO_RESOLVE__(M) M
#define MACRO_RESOLVE_(V, S) MACRO_RESOLVE__(ENABLE_VAR_ ## V ##_## S)
#define MACRO_RESOLVE(var,set) MACRO_RESOLVE_(var, set)

#define ENABLE_VAR_1     MACRO_RESOLVE(1, SET)
#define ENABLE_VAR_2     MACRO_RESOLVE(2, SET)

int main(int argc, char **argv) {

    fprintf(stdout, "VALUE: %d\n", ENABLE_VAR_1);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多