联合是否支持灵活的数组成员?

Does union support flexible array members?

我在union中声明了一个灵活的数组成员,像这样:

#include  <stdio.h>

union ut
{
    int i;
    int a[]; // flexible array member
};

int main(void)
{
    union ut s;
    return 0;
}

编译器报错:

source_file.c:8:9: error: flexible array member in union
     int a[];

但是,声明数组 大小如下:

union ut
{
    int i;
    int a[0]; // Zero length array
};

它工作正常。

为什么零长度数组可以很好地并集?

int a[] 是 C 标准符号(因为 C99)。

int a[0] 是 GNU C 语法,早于 C99。其他编译器可能也支持,我不知道。

您的编译器似乎默认为带有 GNU 扩展的 C90 标准,这就是为什么后者可以编译,但第一个可以。

此外,如所述,标准C根本不支持union中的灵活数组成员。


尝试将 -std=c99-std=c11 添加到您的编译器选项 (gcc docs here)。

另外 -pedantic-pedantic-errors 也可能是个好主意,它将强制执行更严格的标准合规性。

而且,除了强制性的,-Wall -Wextra 也不会伤害...

不,联合不支持灵活的数组成员,只支持结构。 C11 6.7.2.1 §18

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.

此外,零长度数组不是有效的 C,它是 gcc 的非标准扩展。你让它工作的原因是因为你的编译器 gcc 配置为编译 "non-standard GNU language" 的代码。如果您希望它为 C 编程语言编译代码,则需要添加编译器选项 -std=c11 -pedantic-errors.

我不确定标准对此有何评论,但 G++ 的联合似乎可以很好地接受灵活的数组。如果你先将它们包装在一个匿名结构中,就像这样:

union {
   unsigned long int  ul;
   char  fixed[4][2];
   struct {
      char  flexible[][2];
   };
};