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

C++ 初始化联合的多个非静态数据成员,c++,c++11,initialization,unions,member-initialization,C++,C++11,Initialization,Unions,Member Initialization,根据标准,考虑以下格式不正确的程序 union Test { int s{3}; float f; Test() {} Test(float f) : f(f) {} // this should be error }; int main() { } C++11标准第12条第6.2.8节规定(重点): 尝试初始化数据库的多个非静态数据成员 union使程序格式错误 但是,所有流行的3个编译器(g++、clang++、MSVC++)

根据标准,考虑以下格式不正确的程序

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

int main() {

}
C++11标准第12条第6.2.8节规定(重点):

尝试初始化数据库的多个非静态数据成员 union使程序格式错误

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

请参阅在g++上测试的实时演示

请参阅在clang++上测试的实时演示


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

它不是格式错误,因为
s
是构造函数的一个参数默认构造函数允许初始化
s
成员,因此在那里只初始化一个成员

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

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


第12.6.2/9节:

在非委托构造函数中,如果给定的潜在构造的子对象未由mem初始值设定项id指定(包括由于构造函数没有指定名称而没有mem初始值设定项列表的情况) (初始化器),然后

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

    • (9.1.1)-构造函数的类是一个联合体(9.3),没有指定该联合体的其他变体成员 通过一个mem-initializer-id
    [无关文本]

上面引用的基本意思是,只有在没有mem-initializer-id的情况下,方括号或相等的初始值设定项才会执行


标准中也有这样一种说法,即工会只能有一个大括号或相等的初始值设定项。

现在它被称为f。同样的逻辑也适用,但它仍然不能回答我的问题。问题不在于标识符。为什么第二个构造函数只初始化
f
?如果
Test
是一个结构,它将初始化两个成员。这仍然不能回答我的问题。你的意思是初始化
ints{3}仅出现在默认构造函数
Test()
中,而在构造函数
Test(float f)
中被忽略。请看这里:@Destructor标准说明要么会发生括号初始化,要么会出现构造函数初始值设定项列表,但不能同时出现两者。命名参数
s
f
数据
不会改变任何东西。它用于初始化成员
f
@Nelxiost,据我所知,OP的问题不是命名变量,他更改了名称,试图让读者更清楚。问题是,当程序在标准中被认为格式不正确时,如何在这些编译器中编译。@Mike:看看我在这里发现了什么类似的东西:@Mike如果你看一下编辑,他将参数名从
data
改回
f
。这并不能让读者更清楚。@Mike:如果你能回答这个问题就更好了