C99:联盟内的灵活阵列?

TLW*_*TLW 6 c struct c99 flexible-array-member gnu99

我试图将使用struct hack转换为使用灵活的数组成员,只是遇到以下错误消息:

错误:使用灵活数组成员的结构无效

(GCC 4.8.1,gnu99,MinGW)

在尝试追踪消息的原因之后,我将其提炼到以下相对最小的情况:

struct a {
    union {
        struct {
            int b;
            int c[];
        } d;
    } e;
};
Run Code Online (Sandbox Code Playgroud)

换句话说,具有灵活数组成员的结构看不到能够放入结构中的并集内,即使联合是结构的最后一个成员.

(请注意,将一个灵活的数组成员直接放在联合内部似乎确实有效.)

现在:除了恢复结构黑客(将c声明为长度为1的数组)之外,还有什么方法可以解决这个问题吗?指向联合内部结构的指针可以工作,但是会遇到额外的间接层.

Jon*_*ler 4

C11 标准 (ISO/IEC 9899:2011) 规定:

\n
\n

\xc2\xa76.7.2.1 结构和联合说明符

\n

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

\n
\n

在您的示例中, 的最后一个成员struct a不是灵活数组成员。它是一个union包含 a 的数组struct,具有灵活的数组成员。

\n

不过,你必须非常努力地工作才能gcc抱怨;它需要-pedantic编译器选项。

\n

  • 简而言之,您可能会继续使用结构黑客,直到您可以重新设计结构,这样就不再需要它了。请注意,“struct a”在并集之后不能包含任何内容(因为布局的工作方式)。或者通过使用指向具有灵活数组成员的结构的指针来进行额外的间接级别。我建议在拒绝该解决方案之前先衡量性能。 (2认同)