Boost logo

Boost :

Subject: Re: [boost] [shared_ptr] calling functions by reference
From: Lars Viklund (zao_at_[hidden])
Date: 2011-05-29 01:48:40


On Sun, May 29, 2011 at 12:51:44AM -0400, Sid Sacek wrote:
> -----Original Message-----
> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]] On Behalf Of Lars Viklund
> Sent: Sunday, May 29, 2011 12:10 AM
> To: boost_at_[hidden]
> Subject: Re: [boost] [shared_ptr] calling functions by reference
>
> > Concurrent access to different shared_ptr instances in the same family
> > (sourced from the same source) is safe.
> > Concurrent access to a single shared_ptr instance is generally unsafe.
>
> You are confirming my suspicion about multi-threading issues.

The above is paraphrased from the documentation, which is more precise
than me, so do read the documentation on thread safety of shared_ptr:
http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#ThreadSafety

> > Passing the shared_ptr by reference puts the onus on you to ensure that
> > the shared_ptr instance you pass in is valid for the duration of the
> > function call, which is non-trivial in general.
>
> I understand. But doesn't it help to have guidelines and standards when it comes to working with shared_ptr<>?

Guidelines are fine things indeed but they are dangerous if you do not
cover the rationale for them. My set of guidelines here (and for most
other parameter passing) are:
* pass by value when affordable;
* pass by reference-to-const-T when copies are not affordable;
* pass by reference-to-T where mutation of the argument is required.

> > Examples of the above would be foo(some_global_ptr); or foo(bar->baz);
> > where some_global_ptr is destroyed somewhere deep in the call chain, or
> > bar is destroyed during the call sequence.
>
> If I understand you correctly, somebody performed a reset() on something along the call sequence. Would I be correct in saying that if reset() isn't used in a busy call sequence, then this problem wouldn't arise? Wouldn't using a const-reference, like you mention below, identify potential problems like that?

Someone could have replaced an ancenstor of the shared_ptr object. You
do not need to explicitly invoke reset to reduce lifetimes. In the
example above, bar could be modified by something you call.

References-to-const does not limit what other entities can do, but
restricts what _you_ and whoever you call directly can do to your
particular view of the instance. It is impossible for you to assign to
(or reset() or any other mutation of) the shared_ptr through a
reference-to-const, nor can anyone your reference is passed to.

> > I've had real-life bugs of this kind. It's not pretty. Unless you have a
> > genuine reason to access the same instance, try to avoid passing it by
> > reference-to-non-const. If you feel you need to avoid the non-free
> > copying cost, pass it by reference-to-const.

As above, reference-to-const is not a panacea, but every little bit of
aid helps, as it eliminates one class of faults mentioned elsewhere in
the thread as well (assigning to it, reset()ing it).

-- 
Lars Viklund | zao_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk