为什么灵活数组成员的静态初始化有效?

我已经为菜单编写了以下基本代码:

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标准,不允许以这种方式初始化柔性arrays成员。

C11:6.7.2.1结构和联合说明符(第20-21页):

21示例2声明后:

 struct s { int n; double d[]; }; 

结构struct具有灵活的数组成员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手册:6.17长度为零的数组 :

相反, 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 } };