I\'ve been reading quite a number of discussions about performance issues when smart pointers are involved in an application. One of the frequent recommendations is to pass a sm
As pointed out in C++ - shared_ptr: horrible speed, copying a shared_ptr
takes time. The construction involves an atomic increment and the destruction an atomic decrement, an atomic update (whether increment or decrement) may prevent a number of compiler optimizations (memory loads/stores cannot migrate across the operation) and at hardware level involves the CPU cache coherency protocol to ensure that the whole cache line is owned (exclusive mode) by the core doing the modification.
So, you are right, std::shared_ptr
may be used as a performance improvement over just std::shared_ptr
.
You are also right that there is a theoretical risk for the pointer/reference to become dangling because of some aliasing.
That being said, the risk is latent in any C++ program already: any single use of a pointer or reference is a risk. I would argue that the few occurrences of std::shared_ptr
should be a drop in the water compared to the total number of uses of T&
, T const&
, T*
, ...
Lastly, I would like to point that passing a shared_ptr
is weird. The following cases are common:
shared_ptr
: I need a copy of the shared_ptr
T*
/T const&
/T&
/T const&
: I need a (possibly null) handle to T
The next case is much less common:
shared_ptr&
: I may reseat the shared_ptr
But passing shared_ptr
? Legitimate uses are very very rare.
Passing shared_ptr
where all you want is a reference to T
is an anti-pattern: you force the user to use shared_ptr
when they could be allocating T
another way! Most of the times (99,99..%), you should not care how T
is allocated.
The only case where you would pass a shared_ptr
is if you are not sure whether you will need a copy or not, and because you have profiled the program and showed that this atomic increment/decrement was a bottleneck you have decided to defer the creation of the copy to only the cases where it is needed.
This is such an edge case that any use of shared_ptr
should be viewed with the highest degree of suspicion.