析构函数调用的次数超过了它应该调用的次数。MSVC中的错误与否?
这个程序:
#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,即三次调用析构函数,为什么?
仅在 MSVC 中。Clang 和 GCC 输出B~B~B(最有可能是正确的)。
有趣的是:如果你取消对 copy-ctor 的注释,它会输出BcopyB~B~B,这是正确的(析构函数调用了两次)。
它是 MSVC 编译器中的错误吗?或者这是正确的行为?
(Visual Studio 2019 最新,cl.exe版本 19.28.29337)
回答
如果打印地址:
#include <stdio.h>
struct B {
B() { printf(" B() <%p>n", (void*)this); }
~B() { printf("~B() <%p>n", (void*)this); }
};
struct C : B { };
void f(B b) { }
int main() {
C c;
f(c);
}
输出是:
B() <000000A013FFFAC4>
~B() <000000A013FFFAA0>
~B() <000000A013FFFBA4>
~B() <000000A013FFFAC4>
如您所见,没有对象被破坏 2 次。似乎有一个临时的参与,据我所知,这是不允许的。这让我相信这是一个错误。这只发生在复制构造函数是微不足道的时候。由于析构函数不是微不足道的,它是可观察的行为,不在 as-if 规则中。