初始化多个联合的非静态数据成员

Initialize more than one non static data member of union

本文关键字:静态 数据成员 初始化      更新时间:2023-10-16

考虑以下程序,这些程序按照标准是病态的

union Test {
    int s{3};
    float f;
    Test() {}            
    Test(float f) : f(f) {} // this should be error
  };
int main() {
}

c++ 11标准N3376第12条第6.2.8节说(强调我的):

对象的多个非静态数据成员初始化的尝试联合使得程序不正确

但是所有流行的3种编译器(g++, clang++, msvc++)编译上述程序时都没有产生任何编译错误或警告。我认为编译器在这个程序中给出诊断是必要的。程序在编译时应该失败。

查看在g++上测试的实时演示。

查看clang++上的实时演示。

这里所有的编译器都是按标准坏的吗?这是编译器错误吗?

默认构造函数允许初始化s成员,因此只初始化一个成员。

参数化构造函数只初始化f成员,因此在那里只初始化一个成员。

每个构造函数只允许初始化一个成员,因此程序是格式良好的。


来自N4594(即将到来的c++ 17标准)§12.6.2/9:

在非委托构造函数中,如果给定的潜在构造子对象没有由mem-initializer-id指定(包括由于构造函数没有mem-initializer-list而没有的情况) ctor-initializer ),那么

  • (9.1) -如果实体是具有默认成员初始化项(9.2)的非静态数据成员,并且

    • (9.1.1) -构造函数的类是联合(9.3),并且不指定该联合的其他变体成员…
    (无关的文本)

上面的引语基本上是说,大括号或相等初始化器只有在没有mem-initializer-id时才会执行。

标准中也有语言规定一个联合只能有一个大括号或等号初始化式

这不是错误的,因为s是构造函数的参数