关于匿名结构和联盟的C标准:
6.7.2.1 p13.一个未命名的成员,其类型说明符是一个结构说明符 没有标签被称为匿名结构;一个未命名的成员,其类型 说明符是没有标记的联合说明符,称为匿名 联盟。 考虑匿名结构或联合的成员 成为包含结构或联盟的成员。这适用 如果包含的结构或联合也是匿名的,则递归地进行。
注意强调:而不是匿名struct / union的成员在包含struct / union的范围中,而是完全成员。但是还有责任:
6.7.2.1 p16.联合的大小足以包含其中最大的成员。最多一个成员的值可以随时存储在union对象中。指向联合对象的指针(适当转换)指向其每个成员(或者如果成员是位字段,则指向它所在的单位),反之亦然。
总而言之,这些似乎意味着(命名)联盟中的匿名结构的成员表现得像联合的共同位置,相互排斥的成员。所以以下内容应该有效:
union Foo
{
struct
{
char a;
char b;
};
};
int main(void) {
union Foo f;
assert(&f == &(f.a) && &f == &(f.b));
}
当然,它没有,我们也不希望它......如果他们像上面那样工作,那么他们就没有理由成为匿名结构/工会。尽管如此,该标准在这一点上似乎毫不含糊。我有什么遗失的吗?
答案 0 :(得分:8)
这看起来像是措辞上的问题,它们不应重叠。
Defect Report (DR) 499对此进行了介绍,该问题询问:
给出以下代码:
union U { struct { char B1; char B2; char B3; char B4; }; int word; } u;
B1,B2,B3和B4的存储区是否重叠?
根据6.7.2.1#13,成员在存储时应重叠,因为它们 成为“联盟U”的成员。
似乎至少有一个实现(GCC) 不要认为它们是重叠的。
至少一种实施 (IBM的XL LE AIX)将它们作为标准重叠 当前状态。
委员会的回应是:
存储空间不重叠。
在DR 502中将发现一个相关的问题,并且可以通过协调措辞来解决这两个问题。
和
将§6.7.2.1p13更改自:
没有标签的结构类型的未命名成员称为匿名结构;没有标签的union类型的未命名成员是 称为匿名联合。匿名结构的成员或 联合被视为包含结构的成员,或 联盟。如果包含结构或联合,则递归适用 也是匿名的。
收件人:
没有标签的结构类型的未命名成员称为匿名结构;没有标签的union类型的未命名成员是 称为匿名联合。匿名成员的姓名 结构或联合添加到包含的名称空间 结构或联合。如果包含 结构或联合也是匿名的。
将足以解决问题。