#include <memory> struct foo { }; int main() { std::make_shared<foo>(); }
The asssembly generated by both g++7
and clang++5
with -fno-exceptions -Ofast
for the code above:
Contains a single call to operator new
if -fno-rtti
is not passed.
Contains two separate calls to operator new
if -fno-rtti
is passed.
This can be easily verified on gcc.godbolt.org (clang++5
version):
Why is this happening? Why does disabling RTTI prevent make_shared
from unifying the object and control block allocations?
Why does disabling RTTI prevent make_shared from unifying the object and control block allocations?
You can see from the assembler (just pasting the text is really preferable to both linking and to taking pictures of it) that the unified version doesn't allocate a simple foo
but an std::_Sp_counted_ptr_inplace
, and further that that type has a vtable (recall it needs a virtual destructor in general, to cope with custom deleters)
mov QWORD PTR [rax], OFFSET FLAT: vtable for std::_Sp_counted_ptr_inplace<foo, std::allocator<foo>, (__gnu_cxx::_Lock_policy)2>+16
If you disable RTTI, it can't generate the inplace counted pointer because that needs to be virtual.
Note that the non-inplace version still refers to a vtable, but it seems to just be storing the de-virtualized destructor address directly.
Naturally, std::shared_ptr
will be implemented with the assumption of the compiler supporting rtti
. But it can be implemented without it. See shared_ptr without RTTI? .
Taking a cue from this old GCC's libstdc++ #42019 bug. We can see that Jonathan Wakely added a fix to make this possible without RTTI.
In GCC's libstdc++, std::make_shared
uses the services of std::allocated_shared
which uses a non-standard constructor(as seen in the code, reproduced below).
As seen in this patch, from line 753, you can see that getting the default deleter simply requires using the services of typeid
if RTTI is enabled, otherwise, it requires a separate allocation that doesn't depend on RTTI.
EDIT: 9 - May -2017: removed copyrighted code previously posted here
I haven't investigated libcxx
, but I want to believe they did similar thing....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With