繁体   English   中英

使用 `{}` 在 C++ 中聚合初始化联合

[英]Aggregate initialization of a union in C++ with `{}`

在下面的程序中,联合U有两个字段ab ,每个字段都有不同的默认值。 如果使用聚合初始化{}创建U类型的变量,联合的值和活动成员是什么?

#include <iostream>

struct A { int x = 1; };
struct B { int x = 0; };

union U {
    A a;
    B b;
};

int main() {
    U u{};
    std::cout << u.a.x;
}

令人惊讶的是,编译器在这里出现分歧:Clang 打印1和 GCC 打印0 ,演示: https://gcc.godbolt.org/z/8Tj4Y1Pv1

其中一个编译器是否存在错误,或者标准未定义此处的行为?

Clang 正确,GCC 错误

根据[dcl.init.aggr]/1

聚合是一个数组或 class ([class])

  • (1.1) 没有用户声明或继承的构造函数([class.ctor]),
  • (1.2) 没有私有或受保护的直接非静态数据成员([class.access]),
  • (1.3) 没有虚函数([class.virtual]),和
  • (1.4) 没有虚拟的、私有的或受保护的基类 ([class.mi])。

ABU都是聚合类,尽管之前是非联合聚合类,前者不符合条件。

根据[dcl.init.aggr]/5 [强调我的]:

对于非联合聚合,每个不是显式初始化元素的元素都按如下方式初始化:

  • (5.1) 如果元素有一个默认的成员初始值设定项 ([class.mem]),则该元素从该初始值设定项进行初始化。
  • (5.2) 否则,如果元素不是引用,则从空的初始化列表 ([dcl.init.list]) 复制初始化该元素。
  • (5.3) 否则,程序是病式的。

如果聚合是联合且初始化列表为空,则

  • (5.4) 如果任何变体成员具有默认成员初始值设定项,则该成员从其默认成员初始值设定项进行初始化;
  • (5.5)否则,联合的第一个成员(如果有的话)是从一个空的初始化列表中复制初始化的。

因此

U u{};

是聚合初始化,结果是联合 class 的第一个数据成员,即类型A (非联合聚合类)的数据成员a ,是从空初始化列表中复制初始化的。 由于类型A的单个数据成员x具有默认成员初始值设定项,因此根据上面的[dcl.init.aggr]/5.1 ,数据成员x由其默认成员初始值设定项初始化。

因此,Clang 是正确的,GCC 是错误的。


GCC 错误报告

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM