> What is the size of A? Answer: you never know in C++ due to polymorphism. It might be a B or other subclass. It is truly a variable length operation.
You could easily go around it.
The compiler knows when creating the destructor for B.
In your example, to have correct C++, you need to have declared a virtual destruct-or for B. You could encode the size of B in a static offset from the virtual destructor or simply as a return value from it.
This is not how it is done now, mainly because how free was designed in C.
free() design is a terrible mistake. Probably one of the worst design mistake of C with the null terminated / no-length specified string and the preprocessor.
But it's possible for `delete tmp;` to call a user-defined `operator delete()` in the derived class! https://godbolt.org/z/hvePa6jMP
The way this works under the hood is that every polymorphic class has two destructors (so two destructor entries in the vtable): the "complete object destructor" is the ~A() you know from C++, and then there's also the "deleting destructor" which combines ~A() + delete.
So the deleting destructor can call free() while knowing the derived object size, even for a delete-via-base-class-pointer.
At least in the MSVC implementation, "delete tmp;" calls "operator delete" polymorphically, through a hidden virtual function. I think this is because derived classes may override "operator delete"?
[–] 1718627440 4 days ago
[–] dragontamer 4 days ago
Consider:
What is the size of A? Answer: you never know in C++ due to polymorphism. It might be a B or other subclass. It is truly a variable length operation.And secondly, the destructor cannot tell if it's f() or g()
[–] adev_ 4 days ago
You could easily go around it.
The compiler knows when creating the destructor for B.
In your example, to have correct C++, you need to have declared a virtual destruct-or for B. You could encode the size of B in a static offset from the virtual destructor or simply as a return value from it.
This is not how it is done now, mainly because how free was designed in C.
free() design is a terrible mistake. Probably one of the worst design mistake of C with the null terminated / no-length specified string and the preprocessor.
[–] dgrunwald 4 days ago
The way this works under the hood is that every polymorphic class has two destructors (so two destructor entries in the vtable): the "complete object destructor" is the ~A() you know from C++, and then there's also the "deleting destructor" which combines ~A() + delete.
So the deleting destructor can call free() while knowing the derived object size, even for a delete-via-base-class-pointer.
[–] cowlevel 3 days ago