7

我指的是来自开源项目tig的代码示例。这是一个很棒的工具!

文件:tig.c

我正在努力寻找定义请求枚举的原因,如下所示:

enum request {
#define REQ_GROUP(help)
#define REQ_(req, help) REQ_##req

        /* Offset all requests to avoid conflicts with ncurses getch values. */
        REQ_UNKNOWN = KEY_MAX + 1,
        REQ_OFFSET,
        REQ_INFO,

        /* Internal requests. */
        REQ_JUMP_COMMIT,

#undef  REQ_GROUP
#undef  REQ_
};

甚至还有结构..

static const struct request_info req_info[] = {
#define REQ_GROUP(help) { 0, NULL, 0, (help) },
#define REQ_(req, help) { REQ_##req, (#req), STRING_SIZE(#req), (help) }
        REQ_INFO
#undef  REQ_GROUP
#undef  REQ_
};

可以看出REQ_GROUP已经#defined 多次造成混乱.. 至少对我来说。好吧,我知道这样做可能有充分的理由..使用宏在代码中隐藏枚举/结构定义的实际原因是什么?

4

3 回答 3

7

当应该对同一数据源使用不同的处理时,这通常会下降。

例如,您可能会这样做:

#define MY_LIST X(Elem1) X(Elem2) X(Elem3)

接着:

enum MyEnum {
# define X(e) e,

  MY_LIST

  Last

# undef X
};

在这种情况下,使用 的当前定义进行MY_LIST扩展。X

现在,在同一个文件中,我也可以使用MY_LIST创建一个to_string方法

char const* to_string(MyEnum e) {
    switch(e) {
#       define X(e) case e: return #e;

        MY_LIST

        case Last: return "Last";

#       undef X
    }
    return 0;
} // to_string

这样,枚举值的集合只被写入一次,并且枚举和处理它的许多方法都会自动与这个集合保持同步。

于 2013-02-13T13:02:02.967 回答
1

这是为了避免请求列表的重复。该列表只需要在一个地方维护, 的定义REQ_INFO, 枚举和数据结构是通过 和 的适当定义从该列表自动生成REQ_GROUPREQ_

如果没有这些宏,枚举和数据结构将不得不分开维护,注意保持它们彼此一致,涉及更多的工作和更大的错误范围。

于 2013-02-13T13:10:50.943 回答
1

您错过了同一文件中的重要定义:

#define REQ_INFO \
REQ_GROUP("View switching") \
VIEW_INFO(VIEW_REQ), \
\
REQ_GROUP("View manipulation") \
REQ_(ENTER, "Enter current line and scroll"), \
REQ_(NEXT, "Move to next"), \
REQ_(PREVIOUS, "Move to previous"), \
< output omitted as it is too long >

因此,例如,您显示的结构扩展为:

static const struct request_info req_info[] = {
   { 0, NULL, 0, "View switching" },
   < VIEW_INFO also expands to some long structure that was ommited here >
   { 0, NULL, 0, "View manipulation" },
   { REQ_ENTER, ENTER, STRING_SIZE("ENTER"), "Enter current line and scroll"},
   { REQ_NEXT, NEXT, STRING_SIZE("NEXT"), "Move to next"}
   < and so on >
};

正如提到的其他答案,它主要是为了保持多个结构/枚举器同步。

于 2013-02-13T13:12:56.480 回答