【问题标题】:Accessing same-type inactive member in unions访问联合中相同类型的非活动成员
【发布时间】:2016-01-08 12:39:31
【问题描述】:

我有这样的事情:

union DataXYZ
{
    struct complex_t
    {
        float real, imag;
    } complex;

    struct vector_t
    {
        float magnitude, phase;
    } vector;
};

我有一些这些向量,作为通用工作空间内存,我在语义上下文之后相应地使用这些字段。

我知道当最后一个活动成员是另一个字段(和类型?)时,读取联合中的字段是未定义的行为。当类型和布局完全匹配时,这是否重要?

我一直在评论一些其他类似的问题,要求提供保证行为的参考资料,但什么都没有出现 - 因此提出了这个问题。

【问题讨论】:

标签: c++ undefined-behavior unions


【解决方案1】:

是的您可以在这个特殊情况中读取其他成员。

这就是 C++11/14 标准所说的:

9.5 - 工会

在一个联合中,最多可以有一个非静态数据成员处于活动状态 在任何时候,即最多一个非静态数据的值 成员可以随时存储在联合中。

但是该部分之后的注释使您的特定实例合法,因为作出了一项特殊保证为了简化联合的使用

[ 注意:如果一个标准布局联合包含多个标准布局 共享一个公共初始序列(9.2)的结构,如果一个对象 此标准布局联合类型的包含标准布局之一 结构,允许检查任何的公共初始序列 标准布局结构成员;见 9.2。 —尾注 ]

和你的structs 分享一个共同的初始序列:

9.2.16 - 类成员

两个标准布局的共同初始序列 struct (Clause 9) types 是最长的非静态数据序列 声明顺序的成员和位域,从第一个开始 每个结构中的这样的实体,这样对应的实体 具有布局兼容的类型,并且两个实体都不是位域 或者两者都是具有相同宽度的位域。

【讨论】:

  • 紧接在您引用的部分之后的注释使其合法:" [注意:为了简化联合的使用,做出一项特殊保证:如果标准布局联合包含多个标准布局结构共享一个公共初始序列 (9.2),并且如果此标准布局联合类型的对象包含一个标准布局结构,则允许检查任何标准布局结构成员的公共初始序列;见 9.2 . —尾注]"
  • 鉴于此答案的得分为零,并且 cmets 可能会变得有趣,我会在 wiki 它。
  • @Bathsheba 9.2.16 指定“初始序列”是“最长序列 [...] 使得实体具有布局兼容类型 [...]。”,所以我认为在这个如果是整个结构,因为 floatfloat 显然具有布局兼容类型。
  • 参见 [class.mem]/16:“两种标准布局结构(第 9 条)类型的公共初始序列是声明顺序中非静态数据成员和位域的最长序列,从每个结构中的第一个这样的实体开始,使得相应的实体具有布局兼容的类型,并且两个实体都不是位域或两者都是具有相同宽度的位域”。标准示例中的AB 与上述情况相同。
  • 在注释中给出这种保证似乎很奇怪:注释不是规范的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2021-12-26
  • 2020-08-23
相关资源
最近更新 更多