Re: Why is boost::scoped_ptr implemented this way?
From: Philipp Bachmann (ed.soxi_at_nnamhcab.ppilihp)
Date: Thu, 11 Mar 2004 11:11:23 +0100
"Siemel Naran" <SiemelNaran@att.net> wrote in message news:email@example.com...
> But I think to be atomic means that if any sub-part fails, the object
> is unchanged. Or maybe I'm mixing this up with strong exception
> safety. If they want this garauntee,
> void reset(T* p = 0)
> T * ptrsave = ptr;
> ptr = p;
> delete ptrsave;
> catch (...)
> ptr = ptrsave;
> delete p;
> catch (...)
> So in a call to p.reset(new T) if the reset operation failed, 'p'
> would be the same.
This opens the question, whether we take not only the state of
the "scoped_ptr<>", but also the state of callers of member
functions on "scoped_ptr<>" into account, when we talk about
"strong exception safety". In my opinion, if "reset()" fails, it should
"fully" fail - and not take ownership over the instance supplied.
So, according to my definition of "strong exception safety",
if a member function "consume()" potentially taking ownership over other
instances isn't "throw()", then it's unsafe to write
"x.consume(new Y);", because the instance of Y may leak. Instead,
you will have to write something like this:
"Y *y=new Y;
or let "consume()" take a "std::auto_ptr< Y >" instead of "Y *" and
internally assign its argument as the latest operation before returning.
To avoid this kind of problems / the potential notational inconvenience,
I'd like to advice to design functions taking ownership such that they
can be declared "throw()" like e.g. "std::auto_ptr<>::reset()".
Of course, this is both a question of the definition and a bit
theoretical, because you run into trouble anyway, as already stated
by many people, if "delete" throws.