数组元素是否算作常见的初始序列?

时间:2016-03-17 03:20:49

标签: c++ arrays language-lawyer unions

my previous question相关的排序:

数组元素是否算作一个常见的初始序列?

struct arr4 { int arr[4]; };
struct arr2 { int arr[2]; };

union U
{
    arr4 _arr4;
    arr2 _arr2;
};

U u;
u._arr4.arr[0] = 0; //write to active
u._arr2.arr[0]; //read from inactive

根据this cppreference page

  

在具有非联合类类型T1的活动成员的标准布局并集中,允许读取非联合类类型T2的另一个联合成员的非静态数据成员m,前提是m是T1和T2的共同初始序列....

这是合法的,还是非法打字?

1 个答案:

答案 0 :(得分:5)

C ++ 11说(9.2):

  

如果标准布局联合包含两个或多个共享公共初始序列的标准布局结构,   如果标准布局联合对象当前包含这些标准布局结构之一,则允许   检查其中任何一个的共同初始部分。 两个标准布局结构共享一个共同的首字母   序列,如果相应的成员具有布局兼容类型,并且这两个成员都不是位字段或   两个都是具有相同宽度的位字段,用于一个或多个初始成员的序列。

关于不同大小的数组是否形成有效的公共初始序列,3.9说:

  

如果T1和T2两种类型相同,则T1和T2是布局兼容类型

这些数组的类型不同,因此不适用。对于数组没有特殊的进一步例外,因此数组可能不是布局兼容的,并且不会形成共同的初始序列。

但实际上,我知道编译器(GCC):

  • 忽略“公共初始序列”规则,
  • 无论如何都允许类型惩罚,但仅当访问是“通过联合类型”时(如在您的示例中),在这种情况下,间接遵守“公共初始序列”规则(因为“公共初始序列”意味着共同编译器支持的体系结构的初始布局。)

我怀疑许多其他编译器采取了类似的方法。在你的例子中,你通过union对象输入pun,这样的编译器会给你预期的结果 - 从非活动成员读取你应该给你通过非活动成员写的值。