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

标签 c gcc struct initialization flexible-array-member

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

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 结构和 union 说明符(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 } };

关于c - 为什么灵活数组成员的静态初始化有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27852062/

相关文章:

c - 文件 c 中的单词搜索

c - 无法使用opengl在c中旋转移动的物体

php - C 中的 sha512 哈希结果与其他语言(php、python)不同

c++ - 用于非常特殊情况的快速点积

使用 gcc 和终端编译

go - 在go中导入struct,得到 "not a type"错误

gcc - MinGW 4.8.1 C++11 线程支持

C函数中的自赋值

c - 对 C typedef 结构的普遍误解,以及与指针的关系

c - 如何在不同的 if 语句中访问我的结构的元素?