【发布时间】:2021-05-31 21:49:04
【问题描述】:
这个程序:
#include <iostream>
using namespace std;
struct B {
B() { cout << "B"; }
//B(const B& b) { cout << "copyB"; }
~B() { cout << "~B"; }
};
struct C : B {
};
void f(B b) {
}
int main() {
C c;
f(c);
return 0;
}
输出B~B~B~B,即3次调用析构函数,为什么?
仅在 MSVC 中。 Clang 和 GCC 输出 B~B~B(很可能是正确的)。
有趣的是:如果取消注释 copy-ctor,它会输出 BcopyB~B~B,这是正确的(析构函数调用了两次)。
这是 MSVC 编译器中的错误吗?或者这是正确的行为?
(Visual Studio 2019 最新,cl.exe 版本 19.28.29337)
【问题讨论】:
-
它看起来确实像一个错误。可能它正在为“派生到基础的转换”创建一个临时对象,然后将其复制到参数对象。但我认为即使在 C++17 使事情变得更严格之前也不允许这样做,因为通常参数对象是从表达式初始化的。可平凡复制的类型可能有一些角落规则,但具有用户定义析构函数的类不是可平凡复制的。
标签: c++ visual-c++ language-lawyer