初始化 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.
考虑以下根据标准格式错误的程序
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.