匿名联合是否可以在结构中别名成员变量?

Und*_*ant 1 c++ struct unions

假设我有以下C++代码:

struct something
{
  // ...
  union { int size, length; };
  // ...
};
Run Code Online (Sandbox Code Playgroud)

这将创建两个struct访问相同值的成员:sizelength.

将两个成员视为完整别名(即设置大小,然后访问长度,反之亦然)是不确定的行为?是否有一种"更好"的方式来实现这种行为,或者这是一种可接受的实现方式?

mey*_*mer 5

它不是未定义的行为.联合中的两个别名都将访问内存中的相同位置.见下文:

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

如果类型具有不同的初始序列,则不确定.


Mat*_* M. 5

是的,这是允许的并且定义明确。根据§3.10 [basic.lval]:

10/如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:

— 对象的动态类型

[...]

由于在这里我们存储 anint并读取 an int,我们通过与对象相同动态类型的泛左值访问对象,因此一切正常。


对于共享相同前缀的结构,标准中甚至还有一个特殊警告。或者,在标准语中,共享一个公共初始序列的标准布局类型

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

那是:

struct A { unsigned size; char type; };
struct B { unsigned length; unsigned capacity; };

union { A a; B b; } x;

assert(x.a.size == x.b.length);
Run Code Online (Sandbox Code Playgroud)

编辑:鉴于这int不是struct(也不是class)我担心它实际上没有正式定义(我当然在标准中看不到任何东西),但在实践中应该是安全的......我已经将问题带到了isocpp论坛; 你可能发现了一个洞。

编辑:在上述讨论之后,我看到了第 3.10/10 节。