c - C11 中的匿名结构和 union 是否被错误描述?

标签 c language-lawyer c11

C 标准说,关于匿名结构和 union :

6.7.2.1 p13. An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

注意强调:匿名结构/union 的成员不是在包含结构/union 的范围中,而是完全成员。但也有责任:

6.7.2.1 p16. The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

综合起来,这些似乎暗示(命名) union 内的匿名结构的成员表现得像共同定位的、互斥的 union 成员。所以以下应该有效:

union Foo
{
    struct
    {
        char a;
        char b;
    };
};

int main(void) {
    union Foo f;
    assert(&f == &(f.a) && &f == &(f.b));
}

当然,它不会,我们也不希望它...如果它们像上面那样工作,就没有理由使用匿名结构/union 。尽管如此,标准在这一点上似乎毫不含糊。有什么我想念的吗?

最佳答案

长话短说

这看起来像是一个措辞问题,它们不应该重叠。

详情

这包含在 Defect Report (DR) 499 中它问:

Given the following code:

union U {   
 struct {
   char B1;
   char B2;
   char B3;
   char B4;  
 };  
int word; 
} u;

Does the storage of B1, B2, B3 and B4 overlap?

According to 6.7.2.1#13, the members should overlap in storage as they become members of 'union U'.
At least one implementation (GCC) seems to NOT consider them to be overlapping.
At least one implementation (IBM's XL LE AIX) considers them to be overlapping as the standard currently states.

委员会的回应是:

The storage does not overlap.

A related issue is to be found in DR 502 and both may be resolved with coordinated wording changes.

和(添加了重点)

Change §6.7.2.1 p13 from:

An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

到:

An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type with no tag is called an anonymous union. The names of members of an anonymous structure or union are added to the name space of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

将充分解决问题。

关于c - C11 中的匿名结构和 union 是否被错误描述?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49657053/

相关文章:

c - 在 malloc 的结构中初始化原子标志

c++ - 数据的 mmap 和页面对齐 - 这会提高性能吗?

c++ - 在类模板的其他未定义成员类的显式特化中定义隐藏 friend 是否合法?

c++ - 函数返回另一个函数

c++ - 功能转换符号 T(x) 和 static_cast<T>(x) 之间的区别

您能否始终访问包含 C 中结构数据的适当对齐的缓冲区?

c - 为什么与 bool 的比较在 C11 中不转换为 bool?

c - 让 getchar 只读取一个字符

c - 如何将二进制数组打印为字符

c - 如何将参数传递给程序集?