【问题标题】:How to relate X-macro to array of function pointer如何将 X 宏与函数指针数组相关联
【发布时间】:2020-11-16 10:36:24
【问题描述】:

我应用 X-macro 机制来获取枚举到字符串的关系。

#define CMD_TABLE \
                     X(cmd_A)\
                     X(cmd_B)\
////////////////////////////////////
typedef enum
{
    EMPTY, 
#define X(x) x,
    CMD_TABLE
#undef X
}cmd_t;
////////////////////////////////////
const static struct
{
    char* name;
    cmd_t index;
} conversionMap[] = {
#define X(x) {#x, x},
        CMD_TABLE
#undef X
};

然后,此函数将字符串转换为枚举。

cmd_t str2enum(const char* str);

最后,将枚举作为数组的索引,调用相应的函数。

(*func[index])();

这种方法有个很大的问题,就是强制程序员记住枚举到函数的映射关系。

也就是说,在初始化阶段,以下函数的顺序

void (*func[])(void) = 
{
    &cmd_A_function,
    &cmd_B_function,
};

需要和CMD_TABLE一样。

此外,一旦CMD_TABLE 增长,代码的维护就会变得越来越糟糕,因为

  1. 如果一个命令不支持,人们可能会在函数指针数组中删除错误的行。

  2. 如果我想知道cmd_Z 做了什么,我必须从 1 数到 26。

  3. CMD_TABLEvoid (*func[])(void) 的列表将彼此远离,因此程序员需要在两个地方编写代码才能添加一个功能。

【问题讨论】:

  • 为什么不使用 X 宏的第三种变体?或者更好的是,使用 X-macros 的 undef-free 版本。
  • 您可以再次使用您的CMD_TABLE,将X(cmd_A) 转换为&cmd_A_function, 的X 宏。真的?但你确实知道怎么做,不是吗?
  • 枚举开头的EMPTY 破坏了枚举和数组索引之间的一致性。不是个好主意。
  • 去掉第一个EMPTY枚举,这种做法只会带来问题。

标签: c c-preprocessor function-pointers x-macros


【解决方案1】:

您已经使用过两次 X-macro。
您可以第三次使用它。
这是一个如何做到这一点的建议,使用你前两次应用的丑陋的 undef-using 模式:

void (*func[])(void) = 
{
#define X(x) &x##_function,
    CMD_TABLE
#undef X
};

【讨论】:

  • 这种宏很棘手。如果这对您来说失败,请提供-E 编译器运行的输出(即预处理代码)并将其与应有的结果进行比较。然后我会尽力修复它。
  • 丑不丑,我相信这是最常用的X宏写法。
  • @Lundin 是的。可惜。
猜你喜欢
  • 2016-10-06
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 2012-09-07
相关资源
最近更新 更多