【发布时间】:2010-11-02 03:05:28
【问题描述】:
【问题讨论】:
标签: c++ c++11 anonymous-types unions
【问题讨论】:
标签: c++ c++11 anonymous-types unions
假设匿名联合不需要声明为静态的,并且编译器遇到这两个翻译单元(在预处理之后):
文件1:
union {
int a;
char b;
};
// Further contents referring to a and b
文件2:
union {
int a;
char b;
};
// Further (different) contents referring to a and b
这两个联合是同一个对象,还是应该是不同的对象?
我认为,为了避免此类无法回答的问题,已决定必须将命名空间范围的匿名联合声明为静态的。
【讨论】:
我的猜测是,如果允许以非静态方式定义联合,它可能会违反 ODR (one definition rule)
【讨论】:
我的最佳猜测:
如果它是非静态的,它可以被其他代码引用。但是其他代码会怎么称呼它?它是匿名的。因此,需要将匿名联合限制在某个局部范围内;因此,它应该被声明为静态的。
但这只是一个猜测。语言设计师可以按照他们想要的方式设计事物。有时他们的选择是任意的,只是因为必须做出一些选择。
【讨论】:
$9.5/5- union { 成员规范 } ;被称为 匿名工会; 它定义了一个未命名类型的未命名对象。
我猜它应该是静态的,以便可以按照全局静态对象的规则初始化对象。如果它不是静态的并且对象没有名称,那么如何初始化它?
编辑2:
重新思考...
匿名工会的成员具有内部联系。此外,默认情况下,全局名称具有外部链接,除非它们具有内部链接。如果匿名联合的名称具有外部链接,则匿名联合的成员不可能具有内部链接。因此,匿名联合使用“静态”存储类说明符声明,以便匿名名称本身具有内部链接。
【讨论】:
静态要求从来没有任何理由,应该将其删除。编译器确实并且应该将联合中的多个元素视为共享相同地址的多个单独的全局变量。实际上,这意味着编译器允许将多种类型应用于同一地址。由于全局匿名联合的范围是全局范围,因此在匿名联合中命名元素的规则应该(并且是)与命名全局变量的规则相同。即匿名联合元素名称必须是唯一的。至于联合的初始化——联合的初始化和简单变量的初始化没有区别。关于静态联合的另一点——联合的值和类型取决于时间。请注意,一次只有一个值可以占用联合,而不管其中的元素数量如何。声明联合开始的原因是允许相同的地址在不同的时间动态地用于不同的类型。这就是为什么静态联合是用词不当而一些编译器直接忽略它的原因。
【讨论】: