Sne*_*tel 17 c language-lawyer c11
关于匿名结构和联合,遵守C标准:
6.7.2.1 p13. 类型说明符是没有标记的结构说明符的未命名成员称为匿名结构; 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.如果包含的结构或联合也是匿名的,则递归应用.
注意强调:而不是匿名struct/union的成员在包含struct/union 的范围内,它们是它的完全成员.但是有责任:
6.7.2.1 p16.联合的大小足以包含其最大的成员.最多一个成员的值可以随时存储在union对象中.指向适当转换的union对象的指针指向其每个成员(或者如果成员是位字段,则指向它所在的单位),反之亦然.
总而言之,这些似乎意味着(命名)联合中的匿名结构的成员表现得像联合的共同位置,相互排斥的成员.所以以下应该有效:
union Foo
{
struct
{
char a;
char b;
};
};
int main(void) {
union Foo f;
assert(&f == &(f.a) && &f == &(f.b));
}
Run Code Online (Sandbox Code Playgroud)
当然,它没有,我们也不希望它......如果他们像上面那样工作,那么没有理由建立匿名结构/联盟.尽管如此,该标准在这一点上似乎毫无疑问.有什么我想念的吗?
这看起来像一个措辞问题,它们不应该重叠.
这在缺陷报告(DR)499中有所涉及,其中要求:
给出以下代码:
Run Code Online (Sandbox Code Playgroud)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:
没有标记的结构类型的未命名成员称为匿名结构; 没有标记的联合类型的未命名成员称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.如果包含的结构或联合也是匿名的,则递归应用.
至:
没有标记的结构类型的未命名成员称为匿名结构; 没有标记的联合类型的未命名成员称为匿名联合.匿名结构或联合的成员名称将添加到包含结构或联合的名称空间中.如果包含的结构或联合也是匿名的,则递归应用.
将充分解决问题.