联合体支持柔性数组成员吗?

7
我已在联合体中声明了一个灵活的数组成员,就像这样:

#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
};

目前一切运作正常。

为什么零长度数组与union相结合可以正常工作?


2
请展示您的编译命令。 - hyde
1
联合体在编译时更多地是类型的混合。而灵活数组成员则是运行时的实体。 - Some programmer dude
4
删除GNU支持,第二个也会抛出错误。 - Sourav Ghosh
"工作正常"...等等..你的意思是编译吗? - Sourav Ghosh
3个回答

9
不支持灵活数组成员,仅支持结构体。C11 6.7.2.1 §18。
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为“灵活阵列成员”。
此外,零长度数组不是有效的 C 语言,这是 GCC 的非标准扩展。您之所以可以使其工作,是因为您的编译器 GCC 配置为编译“非标准 GNU 语言”的代码。如果您希望它编译 C 编程语言的代码,您需要添加编译器选项“-std=c11 -pedantic-errors”。

8

int a[] 是C标准符号(自 C99 起)。

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

你的编译器似乎默认为带有GNU扩展的C90标准,这就是为什么后者可以编译通过而前者不能。

此外,正如Lundin的回答中所述,标准C根本不支持在union中使用可变大小数组成员。


尝试将-std=c99-std=c11添加到编译器选项中(gcc文档在此)。

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

此外,-Wall -Wextra也不会有坏处...


2
还有-pedantic选项吗? - Sourav Ghosh
2
一个接受 int a[0] 的编译器是不合规的,因为在 C 语言中明确禁止使用零长度数组。 - Lundin
1
GCC没有加上-pedantic选项就不符合标准。 - Antti Haapala -- Слава Україні
@Lundin:符合标准的 C 语言实现可以接受并有用地处理这样的结构,前提是它至少发出一个诊断,并且符合标准的 C 程序(但不是严格符合标准的 C 程序)可以使用这样的结构,前提是存在某个符合标准的 C 语言实现可以接受它。 - supercat

0

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

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

如果使用标准选项(如-std=c11)进行编译,就会出现“在没有命名成员的结构体中使用了灵活数组成员”的错误,这些天已经无法工作了。 - BeeOnRope

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接