【发布时间】: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 增长,代码的维护就会变得越来越糟糕,因为
-
如果一个命令不支持,人们可能会在函数指针数组中删除错误的行。
-
如果我想知道
cmd_Z做了什么,我必须从 1 数到 26。 -
CMD_TABLE和void (*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