我已经为菜单编写了以下基本代码:
typedef struct Menu {
char* title;
unsigned num_submenus;
struct Menu *submenu[];
} Menu;
Menu sub1 = {"Submenu 1", 0, {NULL}};
Menu sub2 = {"Submenu 2", 0, {NULL}};
Menu Main = {"Main Menu", 2, {&sub1, &sub2}}; /* No Error?! */
int main()
{
printf("%s\n", Main.title);
printf("%s\n", Main.submenu[0]->title);
printf("%s\n", Main.submenu[1]->title);
}
浏览一些相关问题似乎是使用灵活数组成员的唯一方法是动态地为其分配内存。但是我的编译器非常乐意编译和运行代码而不会出现任何错误或警告。这是禁止的吗?
我正在使用MinGW gcc 4.6.1并根据C99规则进行编译。
按照C标准,不允许以这种方式初始化柔性阵列成员。
C11:6.7.2.1结构和联合说明符(第20-21页):
21示例2声明后:
struct s { int n; double d[]; };
结构结构 s
有一个灵活的阵列成员 d
。 [...]
22遵循上述声明:
struct s t1 = { 0 }; // valid
struct s t2 = { 1, { 4.2 }}; // invalid
t1.n = 4; // valid
t1.d[0] = 4.2; // might be undefined behavior
初始化 t2
是无效的 (并违反约束)因为 struct s
被视为不包含成员 d
。 [...]
但是,GCC允许灵活数组的静态初始化:
代替 GCC允许灵活的阵列成员的静态初始化。这相当于定义一个包含原始结构的新结构,后跟一个足够大小的数组来包含数据。例如。在下面的, f1
被构造成好像它被宣布为 f2
。
struct f1 {
int x;
int y[];
} f1 = { 1, { 2, 3, 4 } };
struct f2 {
struct f1 f1;
int data[3];
} f2 = { { 1 }, { 2, 3, 4 } };