【问题标题】:Why are global anonymous unions required to be declared as static?为什么需要将全局匿名联合声明为静态?
【发布时间】:2010-11-02 03:05:28
【问题描述】:

C++ 0x draft

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

这是为什么?

【问题讨论】:

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


    【解决方案1】:

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

    文件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
    

    这两个联合是同一个对象,还是应该是不同的对象?

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        我的最佳猜测:

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

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

        【讨论】:

        • 我看不出它在代码的不同部分中的调用可能是问题所在 - 因为它没有被调用任何东西。相反,只有成员被直接引用,并且它们都有名称。匿名的是工会本身,而不是其成员。
        • 我想我正试图深入了解为什么这个功能是这样设计的。顺便说一句,这种行为对 C++0x 来说并不新鲜(尽管我已经引用了 C++0x 草案)——这种行为已经有一段时间了。
        【解决方案4】:

        $9.5/5- union { 成员规范 } ;被称为 匿名工会; 它定义了一个未命名类型的未命名对象。

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

        编辑2:

        重新思考...

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

        【讨论】:

        • 该死的!我不知道如何摆脱双重“定义”
        • 将其设为静态将为它提供“零初始化”。但是为什么根本需要默认(零)初始化呢?它的成员可以通过他们的名字来引用,所以第一次给 anon-union 的成员赋值时,anon-union 将被初始化。我错过了什么?
        • @Vatsan Madhavan:赋值不同于初始化
        • 你是对的。但是..未初始化的全局匿名联合有什么问题?
        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-12
          • 2019-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-21
          • 1970-01-01
          相关资源
          最近更新 更多