我的印象是,访问除最后一组以外的union成员是UB,但是我似乎找不到可靠的引用(除了声称它是UB的答案,但没有标准的任何支持)。

那么,这是未定义的行为吗?

最佳答案

困惑之处在于C明确允许通过联合进行类型处理,而C++(c++11)没有此类许可。



C++的情况:



后来C++的语言允许使用包含带有共同初始序列的struct的并集。但是,这不允许进行类型调整。

为了确定在C++中是否允许联合类型修剪,我们必须进一步搜索。回想一下c99是C++ 11的规范性引用(C99与C11具有类似的语言,允许联合类型对位):



当我们阅读时,它变得特别有趣



因此,对于包含在并集中的原始类型(事实上,ipso实际上具有微不足道的初始化),对象的生存期至少包含并集本身的生存期。这使我们可以调用



假设我们感兴趣的操作是类型操作,即获取一个非 Activity 联合成员的值,并且根据以上所述,我们对该成员所引用的对象具有有效的引用,那么该操作就是左值-右值转换:



然后的问题是,是否通过存储到 Activity 联合成员来初始化作为非 Activity 联合成员的对象。据我所知,事实并非如此,尽管如此:

  • 将联合复制到char数组存储中并返回(3.9:2)或
  • 一个联合会按字节复制到另一个相同类型的联合(3.9:3)或
  • 通过符合ISO / IEC 9899(已定义)的程序元素跨语言边界访问联合(3.9:4注42),然后是

  • 如果定义了非 Activity 成员对并集的访问,并且该访问被定义为遵循对象和值表示形式,则没有上述中介之一的访问是未定义的行为。这对允许对此类程序执行的优化有影响,因为该实现当然可以假定未发生未定义的行为。

    也就是说,尽管我们可以合法地为非 Activity 的工会成员形成一个左值(这就是为什么无需构造即可分配给非 Activity 的成员是可以的),但它仍被认为是未初始化的。

    09-10 00:58
    查看更多