C++ 联合体本身是标准布局类型吗?

C++ 联合体本身是标准布局类型吗?,c++,c++11,C++,C++11,如果我有这样的标准布局类型: struct sl_t { int a; }; union un_t { int b; double q; }; 像这样的联盟: struct sl_t { int a; }; union un_t { int b; double q; }; 我可以强制转换并使用union作为结构类型吗?也就是说,我是否可以假设union本身是标准布局类型,并且数据在内存的开头对齐 un_t obj; sl_t * s = reinterpret_c

如果我有这样的标准布局类型:

struct sl_t
{
  int a;
};
union un_t
{
  int b;
  double q;
};
像这样的联盟:

struct sl_t
{
  int a;
};
union un_t
{
  int b;
  double q;
};
我可以强制转换并使用union作为结构类型吗?也就是说,我是否可以假设union本身是标准布局类型,并且数据在内存的开头对齐

un_t obj;
sl_t * s = reinterpret_cast<sl_t*>(&obj);
s->a = 15;
assert( obj.b == 15 );
un_t obj;
sl_t*s=重新解释铸件(&obj);
s->a=15;
断言(obj.b==15);
或者我必须在union
和obj.b
中获取变量的地址吗


请注意,我已经意识到,如果我将结构存储在union中,C++11标准保证我可以访问sl_t::a和un_t::b,参考9.5-1。

似乎对齐是您的问题,请查看
pragma pack
。结构/联合名称仅引用分配的内存块,如果通过添加更多成员在结构中替换st_.t.a,则强制转换将失败,但如果它仍然是第一个成员,它将工作,因为联合的所有成员都指向与联合本身相同的地址

参见C++标准第9.2.17-21节: 指向标准布局结构对象的指针(使用reinterpret_转换进行适当转换)指向其初始成员(或者如果该成员是位字段,则指向其所在的单元),反之亦然

另见第9.5节:活接头:
“1.在一个联合中,在任何时候最多只能有一个非静态数据成员处于活动状态,也就是说,在任何时候,联合中最多可以存储一个非静态数据成员的值。[注:为简化联合体的使用,我们提供了一项特殊保证:如果一个标准布局联合体包含多个共享公共初始序列的标准布局结构(9.2),如果此标准布局联合类型的对象包含一个标准布局结构,则允许检查任何标准布局结构成员的公共初始序列;请参见9.2.-结束注释]联合的大小足以包含其最大的非静态数据成员。每个非静态数据成员的分配方式与结构的唯一成员相同。”

但是,
&obj.b
不是更短更安全吗?我很好奇你的动机。我仍然需要重新解释它。我主要是好奇,但我确实有一个案例可以方便地依赖它。我很有兴趣知道,没有任何编译器扩展,它是否有效。@edA qa mort-ora-y:I exp我的回答是,是的,它是有效的,但仅如我所解释的。你的第二个评论,在标准中,它实际上在哪里保证工会成员的地址与地址本身相同?这是我没有找到的,但是的,这将使我的转换有效。是的,显然,如果st_.a不再是第一个成员,它将不起作用。你ave分配
sizeof(union)
,虽然union的大小与它最大的成员相同,但我仍然找不到其他成员共享地址的参考。请注意,我实际上同意(所有已知的编译器)正如你所说。我也读了这些内容,我在问题中提到了9.5-1。在内部,每个成员都是标准布局,但这并不意味着工会的地址等于其成员的地址。也就是说,如果工会的成员都是标准布局,那么工会本身就是标准布局类吗?