не вызывался, то это же UB? Типа:
Type t;
t.~Type();
Можно пример кода?
На момент автоматического разрушения t, да.
Если ~T() нетривиален, то в #1 неопределенность: { T t; t.~T(); } /* #1 */
Таак. То есть, сам вызов деструктора - не UB?
В #1 неопределенность, если ~T() - не псевдодеструктор (не от встроенного типа). Скорее всего для встроенных это можно. { T t; t.~T(); t.~T() /* #1 */; }
А если после вызова сделать вот так: Type t; t.~Type(); auto f = t.f; ?
Так нельзя, да. Это out-of-life access.
Вызывать деструктор можно, если есть гарантия, что он не будет вызван повторно при разрушении объекта. Примеры: placement new и union.
При попытке использовать этот объект будет обращение к указателям, по которым уже сделан delete. Ничего хорошего из этого не получится
Ну если есть деструктор - внутри объекта есть какой-то ресурс. Никто не запрещает вызвать деструктор, а потом метод, который к этим ресурсом обращается. В частности, если там были указатели, то по ним был сделан delete и обращение к ним не сулит ничего хорошего
Указатель внутри может не владеть ресурсом, а только "смотреть" на него.
> Никто не запрещает вызвать деструктор, а потом метод, который к этим ресурсом обращается. Запрещает: вызов деструктора завершает время жизни объекта. Все его идентификаторы (имена переменных, ссылки, указатели) прекращают называть его и называют область хранилища, в которой он располагался при жизни. Вызов нестатического метода через такой идентификатор составляет неопределенную операцию безотносительно состава его тела.
С если речь об implicit lifetime type?
А ещё это мог быть деструктор по умолчанию, который вообще ничего не освобождает. В общем случае мы не знаем, что из этого будет
Не имеет значения. "Мертвыми" объектами "типонасыщенно" пользоваться нельзя.
Я имел ввиду, что можно это написать и не будет ошибки компиляции. Понятное дело, что так делать не надо
компилятор имеет право отказать в компиляции, если докажет безусловное возникновение такой ситуации
Ну тот же malloc с 20 стандарта даёт нам сторэйж. И с ним можно работать как с любым из impl lifetime type. В чем подвох?
Так это же про разное: impl-lifetime-type на то и таков, что время жизни начинается, хоть и неявно. В обсуждении выше же речь о доступе вне этого времени.
в том, что этот storage выдан специальной implicit lifetime функцией
Это Warning у gcc. Скажет, что используется неинециализированная переменная. Но если это предупреждение проигнорировать - обращение к полям после вызова деструктора происходит успешно
Some operations are described as implicitly creating objects within a specified region of storage. http://eel.is/c++draft/intro.object#10.sentence-1
С самой памятью деструктор ведь ничего не делает
Зато семантика делает
The properties ascribed to objects and references throughout this document apply for a given object or reference only during its lifetime. http://eel.is/c++draft/basic.life#4.sentence-1
это справедливо лишь для trivially destructible типов
Там более строгая формальность есть через 1, 2.
да, но я решил, что это не добавит ясности ответу, а кратко уже не будет
Отсюда читай
интересно, если напрямую вызвать деструктор, то при уничтожении объекта на стеке будет ли деструктор еще раз вызван
http://eel.is/c++draft/basic.life#9
ну вообще логично да
Обсуждают сегодня