c-我可以用gcc扩展在编译时强制执行显式初始化的数组大小吗



如果某个显式初始化的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,您需要添加对其的检查。这总比冒险出界要好。

此外,对于上面的内容,如果您删除枚举,那么如果您忘记更新数组初始化,编译器将警告您初始化器过多。

最新更新