
On Sun, May 29, 2011 at 12:51:44AM -0400, Sid Sacek wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Lars Viklund Sent: Sunday, May 29, 2011 12:10 AM To: boost@lists.boost.org 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#ThreadSaf...
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@acc.umu.se