-1

考虑以下根据标准格式错误的程序

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++ 上测试的现场演示。

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

4

2 回答 2

4

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

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

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


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

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

  • (9.1) — 如果实体是具有默认成员初始值设定项 (9.2) 的非静态数据成员,并且要么

    • (9.1.1) — 构造函数的类是一个联合 (9.3),并且该联合的其他变体成员没有由mem-initializer-id指定...

    [无关文字]

上面的引用基本上是说,bracket-or-equal-initializer只有在没有mem-initializer-id时才会执行。

标准中还有一种语言说联合可能只有一个大括号或相等初始化器

于 2016-08-20T18:13:05.317 回答
0

它不像s构造函数的参数那样格式错误

于 2016-08-20T18:09:08.960 回答