布局兼容类型的并集 [英] Union of layout-compatible types

查看:122
本文介绍了布局兼容类型的并集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看下面的代码:

struct A {
    short s;
    int i;
};
struct B {
    short s;
    int i;
};

union U {
    A a;
    B b;
};

int fn() {
    U u;
    u.a.i = 1;
    return u.b.i;
}

是否保证fn()返回1?

注意:这是对的后续问题

Note: this is a follow-up question to this.

推荐答案

是的,这是定义的行为.首先让我们看看标准关于AB的内容. [class.prop]/3

Yes, this is defined behavior. First lets see what the standard has to say about A and B. [class.prop]/3 has

如果满足以下条件,则S类是标准布局的类:

A class S is a standard-layout class if it:

  • 没有非标准布局类(或此类数组)或引用的非静态数据成员,
  • 没有虚拟函数,也没有虚拟基类,
  • 对所有非静态数据成员具有相同的访问控制,
  • 没有非标准布局的基类,
  • 最多具有一个任何给定类型的基类子对象,
  • 具有该类及其基类中所有的非静态数据成员和位字段,并且首先在同一类中声明它们,并且
  • [...](在这种情况下,这里什么也没说)
  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions and no virtual base classes,
  • has the same access control for all non-static data members,
  • has no non-standard-layout base classes,
  • has at most one base class subobject of any given type,
  • has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and
  • [...] (nothing said here has any bearing in this case)

所以AB都是标准布局类型.如果我们查看 [class.mem]/23

So A and B are both standard layout types. If we look at [class.mem]/23

如果两个标准布局结构类型的公共初始序列包含两个类的所有成员和位字段([basic.types]),则它们是布局兼容的类.

Two standard-layout struct types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes ([basic.types]).

[class.mem]/22

两种标准布局结构类型的公共初始序列是非静态数据成员和位字段的最长序列(按声明顺序),从每个结构中的第一个这样的实体开始,以便相应的实体具有布局兼容类型,要么两个实体都使用no_unique_address属性([dcl.attr.nouniqueaddr])声明,要么都不声明,并且两个实体都是具有相同宽度的位域,或者都不是位域.

The common initial sequence of two standard-layout struct types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types, either both entities are declared with the no_­unique_­address attribute ([dcl.attr.nouniqueaddr]) or neither is, and either both entities are bit-fields with the same width or neither is a bit-field.

[class.mem]/25

在具有结构类型T1的活动成员的标准布局联合中,允许读取结构类型T2的另一个联合成员的非静态数据成员m,条件是m是T1的公共初始序列的一部分,并且T2;行为就像提名了T1的相应成员一样. [示例:

In a standard-layout union with an active member of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated. [ Example:

struct T1 { int a, b; };
struct T2 { int c; double d; };
union U { T1 t1; T2 t2; };
int f() {
  U u = { { 1, 2 } };   // active member is t1
  return u.t2.c;        // OK, as if u.t1.a were nominated
}

-示例示例"] [注:通过非易失性类型的glvalue读取易失性对象具有未定义的行为([dcl.type.cv]). —尾注]

— end example ] [ Note: Reading a volatile object through a glvalue of non-volatile type has undefined behavior ([dcl.type.cv]). — end note ]

那么我们就有了这样的类,它们具有相同的公共初始序列,布局相同,并且访问非活动类型的相同成员就像访问活动类型的成员一样.

Then we have that the classes have the same common initial sequence, are laid out the same, and accessing the same member of the non-active type is treated as if accessing that member of the active type.

这篇关于布局兼容类型的并集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆