この回答で述べたように、デストラクタを 2 回目に呼び出すだけでは、未定義の動作 12.4/14(3.8) になります。
例えば:
class Class {
public:
~Class() {}
};
// somewhere in code:
{
Class* object = new Class();
object->~Class();
delete object; // UB because at this point the destructor call is attempted again
}
この例では、デストラクタを複数回呼び出すことができるようにクラスが設計されています - 二重削除のようなことは起こりません。が呼び出された時点で、メモリはまだ割り当てられています。delete
最初のデストラクタ呼び出しでは、::operator delete()
メモリを解放するために が呼び出されません。
たとえば、Visual C++ 9 では、上記のコードは機能しているように見えます。UB の C++ 定義でさえ、UB として認定されたものの動作を直接禁止するものではありません。そのため、上記のコードが実装やプラットフォームの仕様を壊すには、いくつかの仕様が必要です。
上記のコードが正確に壊れる理由と、どのような条件でしょうか?