首页 > 解决方案 > 与具有灵活数组成员的匿名结构联合

问题描述

考虑以下两个示例:

1.

union test{
  struct {
      int a;
      int b[];
  };
};


int main(void){
    union test test;
    test.a = 10;
    printf("test.b[0] = %d", test.b[0]); //prints 0, UB?
}

演示

2.

#include <stdio.h>

union test{
    int a;
    int b[]; //error: flexible array member in union
};


int main(void){
    union test test;
    test.a = 10;
    printf("test.b[0] = %d", test.b[0]);
}

演示

行为不清楚。我希望这些示例的行为相同(即第一个示例也无法编译),因为6.7.2.1(p13)

匿名结构或联合的成员被视为包含结构或联合的成员。

因此,我将措辞解释为好像 a unioncontains an anonymousstruct作为成员,anonymous 的成员struct将被视为contains 的成员union

问题为什么第一个示例编译良好而不是第二个示例失败?

标签: cstructlanguage-lawyerunion

解决方案


注意:自首次编写以来,此答案已进行了实质性修改,反映了在发布答案的原始版本所依赖的文件后委员会立场的变化。

匿名结构或联合的成员被视为包含结构或联合的成员。

这是一个难以解释的条款,事实上,至少有两个针对该标准的缺陷报告的主题。正如委员会在其对DR 499的回复中所支持的那样,其意图是出于布局目的将匿名结构视为结构本身是包含结构或联合的成员,但对其成员的访问表示为好像它们是成员包含结构或联合的。

另一方面,DR 502上的公认立场认为,即使是包含灵活数组成员作为其唯一成员的匿名结构,如果它是包含它的结构(不是联合)的最后一个成员,并且至少是另一个成员在它之前。

我发现这些有点不一致,但它们之间的统一主题似乎是该领域标准的意图归结为layout。匿名结构内的灵活数组成员是允许的,只要它位于最里面的命名结构或联合的布局的末尾,考虑到其他成员的考虑,它必须具有非零大小,考虑到成员的事实无论匿名结构是否出现在联合内部,匿名结构的 结构都不会重叠。

提议的委员会对DR 502的回应(不同于其最初的立场)与此一致。它认为结构或联合中的匿名结构必须遵守与其他结构有关灵活数组成员的相同规则,尽管您询问了哪些规定。

委员会似乎没有决定你提出的具体问题,但其决定的主题似乎很明确:“被认为是包含结构或工会的成员”的措辞旨在狭义地解释,作为仅关于访问匿名结构和联合成员的语法。因此,该条款没有说明匿名结构是否可能包含 FAM,以及关于它们何时何地适用的一般规则。这些规则允许您的第一个案例。


推荐阅读