このプログラムは明確に定義されていますか?そうでない場合は、なぜ正確ですか?
#include <iostream>
#include <new>
struct X {
int cnt;
X (int i) : cnt(i) {}
~X() {
std::cout << "destructor called, cnt=" << cnt << std::endl;
if ( cnt-- > 0 )
this->X::~X(); // explicit recursive call to dtor
}
};
int main()
{
char* buf = new char[sizeof(X)];
X* p = new(buf) X(7);
p->X::~X(); // explicit call to dtor
delete[] buf;
}
私の推論:12.4 / 14によると、デストラクタを2回呼び出すことは未定義の動作ですが、正確には次のようになります。
存続期間が終了したオブジェクトに対してデストラクタが呼び出された場合、動作は未定義です。
これは再帰呼び出しを禁止していないようです。オブジェクトのデストラクタが実行されている間、オブジェクトの存続期間はまだ終了していないため、デストラクタを再度呼び出すのはUBではありません。一方、12.4/6は次のように述べています。
本体を実行した後[...]クラスXのデストラクタは、Xの直接メンバーのデストラクタ、Xの直接基本クラスのデストラクタを呼び出します[...]
つまり、デストラクタの再帰呼び出しから戻った後、すべてのメンバーおよび基本クラスのデストラクタが呼び出され、前のレベルの再帰に戻ったときに再度呼び出すとUBになります。したがって、ベースがなく、PODメンバーのみが存在するクラスは、UBなしで再帰デストラクタを持つことができます。私は正しいですか?
