Является ли эта программа корректной, а если нет, то почему именно?
#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;
}
Мое рассуждение: хотя вызов деструктора дважды - это поведение undefined, в соответствии с 12.4/14, он точно говорит следующее:
поведение undefined, если деструктор вызывается для объекта чье время жизни закончилось
Что, по-видимому, не запрещает рекурсивные вызовы. В то время как деструктор для объекта выполняется, время жизни объекта еще не закончилось, поэтому не UB снова вызывает деструктор. С другой стороны, 12.4/6 гласит:
После выполнения тела [...] a деструктор для класса X вызывает деструкторы для прямых элементов X, деструкторы для прямой базы X классы [...]
что означает, что после возвращения из рекурсивного вызова деструктора будут вызваны все деструкторы класса и класса, а их повторение при возврате на предыдущий уровень рекурсии будет UB. Следовательно, класс без базовых и только элементов POD может иметь рекурсивный деструктор без UB. Я прав?