如果某个明确初始化的C数组中的元素数不等于某个值,是否可以强制GCC在编译时引发警告或错误?
考虑以下简单的C程序:
#include <stdio.h>
enum my_enum {
MY_ENUM_FIRST,
MY_ENUM_SECOND,
MY_ENUM_THIRD,
MY_ENUM_COUNT
};
// indexable by my_enum
const char *my_enum_names[] = {
"first",
"second",
"third",
};
int main(void) {
int i;
for (i = 0; i < MY_ENUM_COUNT; i++)
{
printf("%s\n", my_enum_names[i]);
}
}
除非它们在代码中直接相邻,否则开发人员可能不会意识到枚举和数组必须彼此保持“同步”。开发人员可以在枚举中添加条目,但不能在数组中添加条目(反之亦然),因此会暴露出越界漏洞。
我可以在my_enum_names
的定义中添加某种杂注或属性,以便如果其大小不等于MY_ENUM_COUNT
时,编译器将引发警告或错误? strong>
一些说明:
我发誓我以前可能已经使用过GCC的__attribute__
扩展程序之一,但是现在我找不到任何符合我想要功能的文档。
答案 0 :(得分:3)
_Static_assert(sizeof my_enum_names / sizeof *my_enum_names == MY_ENUM_COUNT,
"my_enum_names is the wrong size.");
在语言中添加_Static_assert
之前,您可以使用以下声明来强制出现这种情况下的错误:
extern char my_enum_namesIsTheWrongSize[1];
extern char my_enum_namesIsTheWrongSize[sizeof my_enum_names / sizeof *my_enum_names == MY_ENUM_COUNT];
如果后者中的测试为假,它将尝试声明一个零元素数组,这本身就是一个错误,但是,以防编译器不报告零大小数组的情况,也与前面的声明冲突,因此它应该会生成错误消息。
答案 1 :(得分:0)
怎么样
const char *my_enum_names[MY_ENUM_COUNT] = { ... };
然后,数组将始终包含足够的元素,但有些元素可能是NULL
,然后您需要添加检查。还是比冒险超越界限好。
此外,通过上述操作,如果删除枚举,则如果您忘记更新数组初始化,则编译器将警告您许多初始化方法。