Is this program well-defined, and if not, why exactly?
#include
#include
struct X {
int cnt;
X (int i) : cnt(i) {}
~X()
It comes back to the compiler's definition of the lifetime of an object. As in, when is the memory really de-allocated. I would think it could not be until after the destructor has completed, as the destructor has access to the object's data. Therefore, I would expect recursive calls to the destructor to work.
But ... there are surely many ways to implement a destructor and the freeing of memory. Even if it worked as I wanted on the compiler I'm using today, I would be very cautious about relying on such behavior. There are lots of things where the documentation says it won't work or the results are unpredictable that in fact work just fine if you understand what is really happening inside. But it's bad practice to rely on them unless you really have to, because if the specs say that this doesn't work, then even if it really does work, you have no assurance that it will continue to work in the next version of the compiler.
That said, if you really want to call your destructor recursively and this isn't just a hypothetical question, why not just rip the entire body of the destructor into another function, let the destructor call that, and then let that call itself recursively? That should be safe.