Ce programme est-il bien défini, et si non, pourquoi exactement?
#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;
}
Mon raisonnement: bien que l'invocation d'un destructeur deux fois, c'est un comportement indéfini, par 12.4/14, ce qu'il dit exactement ceci:
le comportement est indéfini si l' le destructeur est appelé pour un objet dont la durée de vie est terminée
Ce qui ne semble pas interdire les appels récursifs. Alors que le destructeur d'un objet est en cours d'exécution, l'objet de la durée de vie n'est pas encore terminée, donc il n'est pas UB pour appeler le destructeur. D'autre part, de 12,4/6 dit:
Après l'exécution de l'organisme [...] destructeur de classe X appelle la les destructeurs pour X direct de membres, les destructeurs de X en direct de la base de les classes [...]
ce qui signifie que, après le retour d'un appel récursif d'un destructeur, tous les états membres et de la classe de base destructeurs auront été appelés, et de les appeler à nouveau lors d'un retour au niveau précédent de la récursivité serait UB. Par conséquent, une classe avec des pas de base, et seul POD peuvent avoir les membres récursive destructeur sans UB. Suis-je le droit?