如果某个显式初始化的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("%sn", my_enum_names[i]);
}
}
除非它们在代码中直接相邻,否则开发人员可能不会意识到枚举和数组必须保持"同步"。开发人员可能会向枚举添加条目,但不会向数组添加条目(反之亦然(,从而暴露出越界漏洞。
我可以在my_enum_names
的定义中添加某种杂注或属性吗?这样,如果其大小不等于MY_ENUM_COUNT
,编译器将抛出警告或错误
一些澄清:
- 我特别指的是显式初始化的数组,这意味着它们的大小在编译时是已知的
- 我指的是GCC编译器,包括编译器扩展
我发誓我以前做过,可能使用了GCC的__attribute__
扩展之一,但现在我找不到任何关于任何功能的文档来满足我的需求。
_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];
如果后者中的测试为false,它将尝试声明一个具有零元素的数组,这本身就是一个错误,但为了防止编译器没有报告零大小的数组,它也会与前面的声明冲突,因此它应该生成一条错误消息。
怎么样
const char *my_enum_names[MY_ENUM_COUNT] = { ... };
然后数组将始终包含足够的元素,但有些元素可能是NULL
,您需要添加对其的检查。这总比冒险出界要好。
此外,对于上面的内容,如果您删除枚举,那么如果您忘记更新数组初始化,编译器将警告您初始化器过多。