Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么需要将全局匿名联合声明为静态联合?_C++_C++11_Anonymous Types_Unions - Fatal编程技术网

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

C++ 为什么需要将全局匿名联合声明为静态联合?,c++,c++11,anonymous-types,unions,C++,C++11,Anonymous Types,Unions,9.5.6在命名名称空间或全局名称空间中声明的匿名联合应声明为静态联合 为什么? 更新- 根据Bart van Ingen Schenau和lothar的回答,到目前为止最好的解释可能是: 如果在两个翻译单元(例如,通过头文件)中遇到相同的全局匿名联合,那么如何满足“一个定义”规则?这两个定义是否被视为相同并合并在一起?或者这两个定义是不同的?如果它们被视为相同的,那么编译器可能正在执行“魔术”,而其他实体则不会执行。如果它们被视为相同的,那么编译器在没有程序员明确同意的情况下这样做。。。因此

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

为什么?


更新-

根据Bart van Ingen Schenau和lothar的回答,到目前为止最好的解释可能是:

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

我的最佳猜测:

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

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

$9.5/5-形式工会的工会{ 成员规范};被称为 匿名联盟它定义未命名类型的未命名对象

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

编辑2:

关于反思


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

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

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

文件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
这两个联合体是同一个对象,还是应该是不同的对象


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

静态要求从来没有理由,应该删除它。编译器确实并且应该将联合中的多个元素视为共享同一地址的多个单独全局变量。实际上,这意味着编译器允许对同一地址应用多个类型。由于全局匿名联合的作用域是全局作用域,因此匿名联合中命名元素的规则应与命名全局变量的规则相同。i、 e.匿名联合元素名称必须是唯一的。至于union的初始化,union和简单变量的初始化没有区别。关于静态联合的另一点——联合的值和类型与时间有关。请注意,无论并集中有多少个元素,一次只能有一个值占用该并集。声明要开始的联合的原因是允许同一地址在不同的时间动态地用于不同的类型。这就是为什么静态联合是一个误称,一些编译器干脆忽略它。

将匿名联合设置为本地而不是全局的

我不认为在代码的不同部分调用它会有什么问题,因为它没有任何调用。相反,只有成员被直接引用,并且它们都有名称。这是工会本身,而不是它的成员。我想我是想了解为什么这个功能是这样设计的。顺便说一句,这种行为对C++0x来说并不新鲜(尽管我引用了C++0x草案)-它已经这样有一段时间了。该死!。我不知道如何摆脱双重“定义”,使其成为静态将为其提供“零初始化”。但为什么需要默认(零)初始化呢?它的成员可以通过它们的名称来引用,因此第一次为anon联合的成员赋值时,anon联合将被初始化。我遗漏了什么?@Vatsan Madhavan:作业与初始化不同,你是对的。但是..一个未初始化的全球匿名联盟有什么问题吗?我认为,结合lothar的ODR反应,这可能是目前为止最好的解释。这加上Bart van Ingen Schenau的反应,可能是目前为止最好的解释。