【问题标题】:Does union support flexible array members?union 是否支持灵活的数组成员?
【发布时间】:2018-02-24 06:45:48
【问题描述】:

我在 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[];

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

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

而且它运行良好。

为什么零长度数组可以很好地联合?

【问题讨论】:

  • 显示你的编译命令。
  • 联合或多或少是编译时类型的合并。灵活的数组成员实际上是一个运行时的东西。
  • 去掉gnu支持,第二个也会报错。
  • “工作正常”...等等..什么?你的意思是编译?

标签: c c99 unions flexible-array-member


【解决方案1】:

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

作为一种特殊情况,结构的最后一个元素具有多个 命名成员可能具有不完整的数组类型;这被称为 灵活的数组成员

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

【讨论】:

    【解决方案2】:

    int a[] 是 C 标准表示法(从 C99 开始)。

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

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

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


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

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

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

    【讨论】:

    • 还有-pedantic,也许吧?
    • 接受int a[0] 的编译器不兼容,因为在 C 中明确禁止零长度数组。
    • GCC 没有-pedantic 是不兼容的。
    • @Lundin:一个符合 C 的实现可以接受并有效地处理这样的构造,只要它发出至少一个诊断,并且符合 C 程序(但不是严格符合 C 程序)可以使用这样的构造,前提是在宇宙中的某个地方存在一个接受它的符合 C 实现。
    【解决方案3】:

    我不确定标准对此会说什么,但 G++ 的联合似乎可以接受灵活的数组。如果您首先将它们包装在匿名结构中,如下所示:

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

    【讨论】:

    • 如果您使用 -std=c11 之类的标准选项进行编译,现在将无法正常工作,给出 error: flexible array member in a struct with no named members
    猜你喜欢
    • 2018-12-10
    • 1970-01-01
    • 2013-08-20
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 2011-03-04
    相关资源
    最近更新 更多