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

Initialize more than one non static data member of union

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

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 节说(强调我的):

An attempt to initialize more than one non-static data member of a union renders the program ill-formed.

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

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

查看在 clang++ 上测试的实时演示 here

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

格式正确,因为 s 是构造函数的参数

默认构造函数让 s 成员被初始化,所以那里只有一个成员被初始化。

参数化构造函数只初始化了f成员,所以那里也只初始化了一个成员。

每个构造函数只让一个成员被初始化,所以程序是良构的。


来自 N4594 (the upcoming C++17 standard) 的 §12.6.2/9:

In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then

  • (9.1) — if the entity is a non-static data member that has a default member initializer (9.2) and either

    • (9.1.1) — the constructor’s class is a union (9.3), and no other variant member of that union is designated by a mem-initializer-id...

    [Unrelated text]

上面的引述基本上说的是 brace-or-equal-initializer 只有在没有 mem-initializer-id.

标准中也有语言说联合可能只有一个 brace-or-equal-initializer.