Boost logo

Boost :

From: Raoul Gough (RaoulGough_at_[hidden])
Date: 2002-04-03 12:37:55

> From: "Peter Dimov" <pdimov_at_[hidden]>
> To: <boost_at_[hidden]>
> Subject: Re: [boost] boost::weak_ptr suggestions
> Date: Mon, 1 Apr 2002 17:31:05 +0300
> Organization: Multi Media Ltd.
> Reply-To: boost_at_[hidden]
> From: "Raoul Gough" <RaoulGough_at_[hidden]>
> > Secondly, I believe it would be better for the get() method to throw or
> > assert when called on an invalidated pointer, instead of transparently
> > returning 0. In my opinion, there is a fundamental difference between
> > two states (null and invalid) which is not observable with the current
> > interface. The addition of a member function like "bool is_valid()
> > would also allow the user code to decide how to deal with an invalid
> > pointer, instead of merging the two distinct states into the one (null)
> > state.
> Right again. However, the primary methods of accessing a weak_ptr are (1)
> constructing a shared_ptr (which does throw) and (2) make_shared. get()
> been retained for efficiency but is not recommended (in multithreaded
> programs.)

So why the difference in error semantics between the single and
multi-threaded idioms? For example, if I converted single-threaded code that
uses get() to thread-safe code using make_shared, I also get changed
semantics for the invalid pointer case.

Incidentally, it looks like the use_count member function can determine
indirectly whether the target still exists or not. It seems a bit obscure
though, seeing as the reference count is really an implementation detail and
distinct from the concept of null/valid/invalid.

> > The big advantage of considering invalid.get() an error is that code
> > then works without error using weak_ptr would have *exactly* unchanged
> > semantics using a plain pointer replacement. This allows (for example) a
> > debug build/release build choice between weak_ptr<T> and T* for
> performance
> > reasons. If weak_ptr<T> silently returns null on invalid pointers, then
> this
> > guarantee cannot be made - what would be undefined use on a plain
> is
> > not detected by the weak_ptr.
> Interesting point. You can write your own get() that does what you want:
> T * get(weak_ptr<T> const & p)
> {
> return shared_ptr<T>(p).get();
> }
> but it's not as efficient as a throwing get(). Most people seem to prefer
> the current get() semantics, though, where 0 is returned.

Well, I can understand that point of view as well - either the weak pointer
has a valid target object or not (in which case null or deleted doesn't
really matter). However, my use of a smart weak pointer is really as a
debugging aid, so I would like the error to be detected as soon as possible
(and distinguished from a null-pointer assertion or SEGV). Short of adding a
policy class template parameter, it would be easy to add a new member
function which does get() with severe checking - along the lines of versus vector.operator[]. Just an idea.

BTW, am I right in thinking that sharede_ptr always maintains an extra weak
reference counter? I mean, even if my code doesn't use weak_ptr, shared_ptr
still has to maintain the extra counter, right? That, combined with the new
thread-safety features seems to cost something like a 10% performance hit in
my smart pointer benchmark code (which sorts indexes to objects containing
two strings each). That's on the total sorting time, not pointer access

It seems like boost is deliberately trying to avoid extra template
parameters for things like policies or allocators. OTOH, it seems a bit
unfair for code to pay for features which it doesn't require (e.g. thread
safety or weak_ptr support). Has the option of adding an additional policy
parameter to the shared_ptr template already been discussed?

Raoul Gough.

Do You Yahoo!?
Get your free address at

Boost list run by bdawes at, gregod at, cpdaniel at, john at