Boost logo

Boost Users :

From: Nevin \ (nevin_at_[hidden])
Date: 2008-05-17 15:26:19


2008/5/16 Noah Roberts <roberts.noah_at_[hidden]>:
> Nevin ":-]" Liber wrote:
>
>> void foo(int const* p)
>> {
>> static int const* pp;
>> if (p && pp) std::cout << *pp << ' ' << *p << std::endl;
>> pp = p;
>> }
>>
>> What should the interface to foo() be such that it doesn't break
>> whether or not foo() keeps a copy of p?
>
> You might consider a shared_ptr. Seems like the perfect place for one.

Let's recap:

NL:If it is keeping the argument, then it cares about
ownership/lifetime, so one should pass a smart pointer to it.

MC:A brief addenda (from my rules of thumb) for non-ownership cases:
    * If the parameter is optional, pass a raw pointer, and the callee
should expect a NULL pointer.
    * If the parameter is not optional, pass a reference

NR:You are creating a dependency on the fact that the called function
will NOT keep a copy

NL:Do you really allocate every single variable in your program on the
heap and store it in a shared_ptr, just in case?

NR:I can't think of what your reasoning is that leads you to this
conclusion from my statements. Care to explain?

NL:What should the interface to foo() be such that it doesn't break
whether or not foo() keeps a copy of p?

NR:You might consider a shared_ptr. Seems like the perfect place for one.

Please go back to the top and reread my rule of thumb (with Marshall's
addendum, which I agree with and use).

There is no safe, general way to have a function or class that takes a
raw pointer or reference such that it can keep a copy of that pointer
or reference and use it later. Someone outside of the function or
class has to make external guarantees about its lifetime. If you have
a function that doesn't keep a copy of a pointer or reference and then
change its implementation so that it does, you are going to have to
revisit every use of that function or class.

In other words, code written like that is fragile and should be used
sparingly. One of the few places I would use code like that is in the
constructor of a smart pointer, where there are very well documented
rules on how to call it. Almost everywhere else where
lifetime/ownership matters past this one function call, I use a smart
pointer instead of a raw one. I prefer not to have fragile code,
where the caller has to "be careful" (which is merely a euphemism for
"be perfect", as any mistake creates a subtle bug).

If you a way of passing a raw pointer or reference where it is always
safe for the called function to copy and use that pointer or reference
later without any external guarantees about the lifetime of the object
pointed/referred to, I'd certainly be interested in hearing about it.

Regards,

-- 
 Nevin ":-)" Liber <mailto:nevin_at_[hidden]> (847) 691-1404

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net