1

我有一个这样的枚举:

enum {
  ID_FOO = 0,
  ID_BAR,
  ID_BAZ
}

以及使用指定初始化器(如 hat)的常量数组:

char* arr[] = {
  [ID_FOO] = "foo stuff",
  [ID_BAR] = "bar stuff",
  [ID_BAZ] = "baz stuff",
  0
}

现在,当我向枚举添加一个值时,例如在ID_FOO但忘记将其添加到数组之后,我会得到一个未初始化数组中的空初始化“洞”。有什么办法可以防止这种情况发生,或者至少从编译器那里得到警告?

非便携式 GCC-only 解决方案很好。

4

2 回答 2

7

一种方法是向您的枚举添加一个标记最大值,您可以使用它来验证该最大值是否与数组中的元素数相同。

enum {
    ID_FOO = 0,
    ID_BAR,
    ID_BAZ,
    // insert new values here

    ID_MAX
}

assert(ID_MAX == (sizeof(arr)/sizeof(arr[0]) - 1));

这是运行时检查;看看C 编译器断言 - 如何实现?有关如何获取编译时错误的想法。

于 2013-04-23T13:36:25.477 回答
4

您可以使用X-Macros使它们保持同步,尽管有些人可能会争论生成的代码是否漂亮。

我们的想法是获取两个结构所需的所有信息并将其放入一个宏中:

条目.inc

ENTRY(ID_FOO, "foo stuff")
ENTRY(ID_BAR, "bar stuff")
ENTRY(ID_BAZ, "baz stuff")

稍后,重新定义您的宏,以便对于您需要构建的每个结构,您从数据中提取适当的部分:

foo.c

/* here define what entry should be for your enums */
#define ENTRY(id, name) id,

enum {
#include "entries.inc"
};

/* and then redefine for the char array and include again */
#undef  ENTRY
#define ENTRY(id, name) [id] = name,

char* arr[] = {
  #include "entries.inc"
  0
};


int main(int argc, char* argv[]) {
  /* whatever */
}
于 2013-04-23T13:40:45.447 回答