使用指定的初始值设定项时,避免空值初始化的漏洞

时间:2013-04-23 13:27:19

标签: c gcc

我有一个这样的枚举:

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之后忘记将它添加到数组中,然后我会在数组中得到一个未初始化的 null-initialized'hole'。有没有办法阻止它,或至少从编译器得到警告?

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

2 个答案:

答案 0 :(得分: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 compiler asserts - how to implement?,了解如何获得编译时错误。

答案 1 :(得分:4)

您可以使用X-Macros让它们保持同步,但有些人可能会争辩结果代码的可爱性。

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

entries.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 */
}