构造函数在 g++ 和 clang++ 中委托给自己
constructor delegates to itself in g++ & clang++
考虑以下程序。我不小心弄错了。
struct T {
int s;
T() : T() {
s=9;
}
};
int main() {
T t;
}
以上代码在某些版本的 g++ 中编译和运行良好,如 g++ 4.8.1(参见现场演示 here ) & clang++ 3.6.0 (see live demo here)和 MSVC++ 2015,但在运行时崩溃。它给我 segmentation fault 错误。我认为这是由于递归,我的意思是递归调用构造函数。但最新版本的 g++ 和 clang++ 无法通过给出以下错误来编译此代码:
g++ 4.9.2 给出以下错误(参见现场演示 here)
prog.cc: In constructor 'T::T()':
prog.cc:3:10: error: constructor delegates to itself
T() : T() {
clang++ 给出以下错误(参见现场演示 here)
main.cpp:4:8: error: constructor for 'T' creates a delegation cycle [-Wdelegating-ctor-cycles]
T() : T() {
^
1 error generated.
所以,这里的问题是,根据标准,哪个编译器是正确的?这些编译器之一有错误吗?上面的程序到底发生了什么?如果我的理解有误,请纠正我。为什么同一个程序在这些编译器的不同版本中表现出不同的行为?
从 C++11 开始,[class.base.init]¶6:
If a constructor delegates to itself directly or indirectly, the program is ill-formed; no diagnostic is required.
所有编译器都是正确的——代码被破坏了,编译器不需要告诉你。此时你有UB;来自 [intro.compliance]¶2:
If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.
考虑以下程序。我不小心弄错了。
struct T {
int s;
T() : T() {
s=9;
}
};
int main() {
T t;
}
以上代码在某些版本的 g++ 中编译和运行良好,如 g++ 4.8.1(参见现场演示 here ) & clang++ 3.6.0 (see live demo here)和 MSVC++ 2015,但在运行时崩溃。它给我 segmentation fault 错误。我认为这是由于递归,我的意思是递归调用构造函数。但最新版本的 g++ 和 clang++ 无法通过给出以下错误来编译此代码:
g++ 4.9.2 给出以下错误(参见现场演示 here)
prog.cc: In constructor 'T::T()':
prog.cc:3:10: error: constructor delegates to itself
T() : T() {
clang++ 给出以下错误(参见现场演示 here)
main.cpp:4:8: error: constructor for 'T' creates a delegation cycle [-Wdelegating-ctor-cycles]
T() : T() {
^
1 error generated.
所以,这里的问题是,根据标准,哪个编译器是正确的?这些编译器之一有错误吗?上面的程序到底发生了什么?如果我的理解有误,请纠正我。为什么同一个程序在这些编译器的不同版本中表现出不同的行为?
从 C++11 开始,[class.base.init]¶6:
If a constructor delegates to itself directly or indirectly, the program is ill-formed; no diagnostic is required.
所有编译器都是正确的——代码被破坏了,编译器不需要告诉你。此时你有UB;来自 [intro.compliance]¶2:
If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.