raw pointer vs unique pointer
Recently at work, we had a discussion about unique pointer that I found interesting and thought it would bring value to share with my network.
1- unique pointer has the same size as a raw pointer:
well, this information is not wrong as per se however it is not factually accurate if a sizeof operator on both a raw pointer and a unique pointer but it doesn't "really mean" they are of the same size
https://github.com/Fadi88/misc_examples/tree/master/unique_pointer
we have two CPP file in this repo (raw.cpp and unique.cpp) when compiled with clang 10.0.0(using no flags) generate a 20% bigger binary for the unique pointer 17 vs 21 kilobytes, and that because even though the object itself doesn't occupy any memory the functions are compiled into the binary and occupy space, this is why it is not reported by the sizeof operator( text section in the previous example increased by a factor of 3.3 when switching to unique pointers)
in fairness, this is more or less a constantly added value, which was exaggerated by the fact that this is a really small code, in big code base the difference won't be a factor of 3 situation
2- unique pointer is a zero-cost abstraction that has a very negligible overhead on the runtime
this is the main part that was problematic, I did some benchmark using the test code in the repo mentioned above (test_ptr.cpp) using GCC 9 with -O2 flag and the raw pointer was faster by 20% to 6 times as a unique pointer for this small piece of code
and that is due to the added functions mentioned at point 1 being executed with the usage of the unique pointer features
copy the code into Godbolt to explore the generated assembly was literally mind-blowing results
just the function that takes ownership of a pointer and uses it and then deletes the memory
in raw pointer in generated 18 assembly instructions using clang
https://www.godbolt.org/z/5bd1rh
same for unique generated a shocking 466 assembly instructions using the same compiler
https://www.godbolt.org/z/7P6T47
Conclusion:
there is no rule that covers all the cases, every case is different and every feature/method use with has radically different behavior depending on the situation,
if I only have a hammer everything for me will look like a nail, one should diversify the toolset being used instead and every time examine the tool being used and deeply inspect the outcomes
I am not advocating against the usage of unique pointers, they are amazing when it comes to exception safety for example to avoid memory leaks( pro-tip: smart pointer don't always guarantee leak-free code there are some corner cases most common is cycles).
A true engineer in heart will always question everything and deeply inspect problems having a generic rule that says "X" is always better than "Y" goes against this spirit
Dr. Christoph Bachhuber, following the discussion we had when the dinosaurs where still on this planet i guess