Re[2]: быстрый new/delete
От: watchmaker  
Дата: 08.12.22 17:59
Оценка: 16 (2) +1
Здравствуйте, fk0, Вы писали:

fk0> Когда ты пишешь delete xxx, то компилятор это превращает в xxx->~XXX(), ::operator delete(xxx).


Это всё же не совсем так: delete xxx — это не синтаксический сахар для xxx->~XXX(); ::operator delete(xxx);.
И если заменить первое на второе, то программы начнут падать.

На самом же деле это только в С++ коде у класса один деструктор, а в скомпилированном коде у класса много деструкторов: например deleting destructor, complete object destructor, base object destructor (в терминологии itanium c++ abi).
И когда ты пишешь delete xxx, то вызывается deleting destructor, а когда пишешь xxx->~XXX(), то вызывается complete object destructor.
Это разные деструкторы именно из-за того, что один нельзя тривиально реализовать через другой, в том числе deleting destructor нельзя выразить как вызов complete object destructor за которым следует вызов ::operator delete(xxx) для того же самого указателя. Пример с виртуальным базовым классом это как раз показывает. И поэтому deleting destructor сначала определяет где была выделена память (для чего нужен неразрушенный объект), потом разрушает поля и базовые классы, и освобождает память для другого указателя, найденного на первом шаге.


P.S. В других ABI (не itanium c++ abi), реализация может чуть отличаться. Например, MSVC генерирует в машинном коде одну функцию, реализующую оба поведения. Но зато эта функция принимает в себя дополнительный параметр (помимо this), говорящий в каком режиме деструктор был вызван, и содержит ветвление уже внутри своего тела. Но главное, что там тоже происходят коррекции адресов.
Отредактировано 09.12.2022 9:44 watchmaker . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.