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

Why does static initialization of flexible array member work?

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

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 结构和联合说明符 (p20-21):

21 EXAMPLE 2 After the declaration:

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

the structure struct s has a flexible array member d. [...]

22 Following the above declaration:

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

The initialization of t2 is invalid (and violates a constraint) because struct s is treated as if it did not contain member d. [...]

但是,GCC 允许灵活数组的静态初始化:

GCC Manual: 6.17 Arrays of Length Zero:

Instead GCC allows static initialization of flexible array members. This is equivalent to defining a new structure containing the original structure followed by an array of sufficient size to contain the data. E.g. in the following, f1 is constructed as if it were declared like 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 } };