Я пытаюсь выяснить, является ли следующее поведение неопределенным. Я чувствую, что это не UB, но мое чтение стандарта делает его похожим на UB:
#include <iostream>
struct A {
A() { std::cout << "1"; }
~A() { std::cout << "2"; }
};
int main() {
A a;
new (&a) A;
}
Цитирование стандарта C ++ 11:
basic.life¶4 говорит: «Программа может закончить время жизни любого объекта, повторно используя хранилище, которое этот объект занимает»
Таким образом, после new (&a) A
исходный объект A
завершил свою жизнь.
class.dtor¶11.3 говорит, что «деструкторы неявно вызываются для построенных объектов с автоматической продолжительностью хранения ([basic.stc.auto]), когда выходит блок, в котором создается объект ([stmt .dcl]) "
Таким образом, деструктор для исходного объекта A
вызывается неявно при выходе из main
.
class.dtor¶15 говорит, что «поведение не определено, если деструктор вызывается для объекта, время жизни которого закончилось ([basic.life]).» *
Так что это неопределенное поведение, поскольку исходный A
больше не существует (даже если новый a
теперь существует в том же хранилище).
Вопрос в том, вызывается ли деструктор для исходного A
, или же вызывается деструктор для объекта , в настоящее время называемого a
.
Мне известно о basic.life¶7 , в котором говорится, что имя a
относится к новому объекту после размещения new
. Но class.dtor¶11.3 явно говорит, что вызывается деструктор объекта , выходящий из области действия , а не деструктор объекта , на который ссылается имя, выходящее из области действия .
Я неправильно истолковываю стандарт или это фактически неопределенное поведение?
Редактировать: Несколько человек сказали мне не делать этого. Чтобы уточнить, я определенно не планирую делать это в производственном коде! Это вопрос CppQuiz , который касается угловых случаев, а не лучших практик.