为什么需要将全局匿名联合声明为静态?

时间:2010-11-02 03:05:28

标签: c++ c++11 anonymous-types unions

C++ 0x draft

  

9.5.6在命名空间或全局命名空间中声明的匿名联合应声明为静态。

为什么呢?


更新 -

基于Bart van Ingen Schenau和Lothar的回应,到目前为止最好的解释可能是:

如果在两个翻译单元中遇到相同的全局匿名联合(例如,通过头文件),那么如何满足一个定义规则?这两个定义是否被视为相同并合并在一起?或者这两个定义是否被视为不同?如果它们被视为相同,那么编译器可能正在做“魔术”,否则对其他实体不起作用。如果它们被视为相同,那么编译器在没有程序员的明确同意的情况下这样做......所以我想通过要求将其声明为静态来强制明确同意。

6 个答案:

答案 0 :(得分:4)

假设不需要将匿名联合声明为静态,并且编译器遇到这两个转换单元(在预处理之后):

File1中:

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

这两个工会是同一个对象,还是应该是不同的对象?

我认为,为了避免像这样的无法回答的问题,已经决定命名空间范围的匿名联合必须被声明为静态。

答案 1 :(得分:1)

我最好的猜测:

如果它是非静态的,则可以被其他代码引用。但是其他代码会怎么称呼呢?这是匿名的。因此,需要将匿名联合限制在某个局部范围内;因此,它应被宣布为静态。

但这只是猜测。语言设计师可以按照自己的方式设计。有时他们的选择是任意的,只是因为必须做出一些选择。

答案 2 :(得分:1)

我的猜测是,如果允许以非静态方式定义联合,则可能违反ODR (one definition rule)

答案 3 :(得分:0)

  

$ 9.5 / 5-联盟形式的联盟{   member-specification};被称为   匿名工会; 它定义了一个未命名类型的未命名对象

我猜它应该是静态的,以便可以根据全局静态对象的规则初始化对象。如果它不是静态的并且对象没有名称,那么如何初始化它呢?

EDIT2:

重新思考......

匿名工会的成员有内部联系。此外,默认情况下,除非内部链接具有内部链接,否如果匿名联合的名称具有外部链接,则匿名联合的成员不可能具有内部链接。因此,使用“静态”存储类说明符声明匿名联合,以便匿名名称本身具有内部链接。

答案 4 :(得分:0)

将匿名联合设为本地而非全局

答案 5 :(得分:-1)

静态要求从来没有任何理由,应该将其删除。编译器确实并且应该将联合中的多个元素视为共享相同地址的多个单独的全局变量。实际上,这意味着编译器允许将多种类型应用于同一地址。由于全局匿名联合的范围是全局范围,因此匿名联合中命名元素的规则应该(和)与命名全局变量的规则相同。即匿名联合元素名称必须是唯一的。至于union的初始化 - union和一个简单变量的初始化没有区别。关于静态联合的另一点 - 联合的价值和类型是时间依赖的。请注意,无论其中的元素数量如何,一次只能有一个值占用并集。声明联合开始的原因是允许相同的地址在不同的时间动态地用于不同的类型。这就是为什么静态联合用词不恰当而有些编译器却忽略它。