From: Marco Manfredini (marco_at_[hidden])
Date: 2000-03-09 17:27:06


Hi there,

> -----Original Message-----
> From: Miki Jovanovic [mailto:miki_at_[hidden]]
> Sent: Thursday, March 09, 2000 9:26 PM
> To: boost_at_[hidden]
> Subject: [boost] Re: Dangerous smart pointers? (Was: Bogus smart
> pointers?)
>
>
> "marco manfredini" <marc-_at_[hidden]> wrote:
> > > If a member function ``commits suicide'' (that is, delete this),
> > > it should understand the consequences.
> > >
> >

// .....

> I beg your pardon. I believe you are wrong here. In your scenario, A
> calls B with parameter ptr. B calls A back, and here A deletes ptr.
> This broke the basic rule that the we were quoting. A does not
> guarantee that the parameter ptr is valid while B is executing. And
> this is plain wrong. Details how you guarantee this are up to you
> (temporary, apply_ptr, any way) but it has to be done.

This seems to be a misunderstanding. My scenarios didn't pass any explicit
parameters, but only the implict 'this', why is too easily overseen.

>
> The way I deal with this is to design modules that use callbacks like
> this differently then the other code. So the callback-enabled code has
> extra safeties to guard against this thing.
>
> In the same time, the rest of the code using smart pointers is not
> burdoned with the complexity of locking/lockable pointers.
>

If efficiency is a concern, one needs to invest some work, to live with the
restricted completeness of the solution. That's a typical situation.

However, apply_ptr wasn't meant as a simple 'explicit' lock for a member
call, but as an general idea, to make smart pointers more flexible by
reflecting the owner/user relationship. With an apply_ptr, I can for example
return an object that is owned by someone else:

class A
{
 scoped_ptr<X> sp;
 scope_apply_ptr<X> get_it() { return scoped_apply_ptr<X>(sp); }
 //...
};

the returned apply_ptr locks sp during his lifetime. Destroying sp, while
apply_ptr's lock it, gives an runtime-error at the place, where a dangeling
pointers are about to come to life.

Of course, everything could be replaced with share_ptr's, but I've made the
objection, that unrestricted share of ownership can be a problem, if a
certain ressource needs to be freed on a defined moment. Using the approach
above, means that every 'borrowed' pointer to sp is orginated at sp and this
helps to identify problems in the program logic. apply_ptr represents a
"temporary share" that is bound to the lifetime of another object.

The owner/user distiction would also prevent the creation of circular in
many situations:

class Button;
class Window
{
 shared_ptr<Button> bu; // controls child
};
class Child
{
 shared_apply_ptr<Window> pa; // asks Parent
};

The nice thing is, that the owner/user relationship between Child and Parent is naturally reflected in the kind of pointers they have to each other.

Greetings,

Marco