Bjarne's exception safe sample

G

George2

Hello everyone,


Here is Bjarne's exception safe sample,

http://www.research.att.com/~bs/3rd_safe.pdf

Code:
template <class T> class Safe {

T* p ; // p points to a T allocated using new
public :
Safe () :p (new T ) { }
~Safe () { delete p ; }
Safe & operator =(const Safe & a) { *p = *a .p ; return *this; }
/ / ...
};
template <class T> class Unsafe { // sloppy and dangerous code
T* p ; // p points to a T
public :
Unsafe (T* pp ) :p (pp ) { }
~Unsafe () { if (!p ->destructible ()) throw E(); delete p; }
Unsafe & operator =(const Unsafe & a)
{
p ->~T (); // destroy old value (§10.4.11)
new (p) T (a .p ); // construct copy of a.p in *p (§10.4.11)
return *this;
}
/ / ...
};

What makes me confused is, the description about why it is not
exception safe,

--------------------
The assignment operator may fail by throwing an exception from T 's
copy constructor. This would
leave a T in an undefined state because the old value of *p was
destroyed and no new value
replaced it.
--------------------

In my study, I can not find a case why there is exception thrown from
Unsafe's copy constructor. Any ideas?

BTW: it is also appreciated if you could share some experiences about
what in your minds does invariant status mean

(in Bjarne's minds, exception safety means making the object into
invariant status). I find the word *invariant* is

somethings hard to understand. :)


thanks in advance,
George
 
B

Bo Persson

George2 wrote:
: Hello everyone,
:
:
: Here is Bjarne's exception safe sample,
:
: http://www.research.att.com/~bs/3rd_safe.pdf
:
:
Code:
: template <class T> class Safe {
:
: T* p ; // p points to a T allocated using new
: public :
: Safe () :p (new T ) { }
: ~Safe () { delete p ; }
: Safe & operator =(const Safe & a) { *p = *a .p ; return *this; }
: / / ...
: };
: template <class T> class Unsafe { // sloppy and dangerous code
: T* p ; // p points to a T
: public :
: Unsafe (T* pp ) :p (pp ) { }
: ~Unsafe () { if (!p ->destructible ()) throw E(); delete p; }
: Unsafe & operator =(const Unsafe & a)
: {
: p ->~T (); // destroy old value (§10.4.11)
: new (p) T (a .p ); // construct copy of a.p in *p (§10.4.11)
: return *this;
: }
: / / ...
: };
:
:
: What makes me confused is, the description about why it is not
: exception safe,
:
: --------------------
: The assignment operator may fail by throwing an exception from T 's
: copy constructor. This would
: leave a T in an undefined state because the old value of *p was
: destroyed and no new value
: replaced it.
: --------------------
:
: In my study, I can not find a case why there is exception thrown
: from Unsafe's copy constructor. Any ideas?

I think Bjarne says it all in the above paragraph. :)

If you destroy a T (p->~T()), and the fail to construct a new T, the
Unsafe object is in an invalid state. Later, when trying to destroy
Unsafe, you will be in real trouble!

:
: BTW: it is also appreciated if you could share some experiences
: about what in your minds does invariant status mean
:
: (in Bjarne's minds, exception safety means making the object into
: invariant status). I find the word *invariant* is
: somethings hard to understand. :)

In invariant is something that doesn't vary, something that is always
true, like an object being in a valid state.

Having an object that cannot be used, and that cannot be safely
destroyed, is just Not Good(tm).


Bo Persson
 
E

Erik Wikström

Hello everyone,


Here is Bjarne's exception safe sample,

http://www.research.att.com/~bs/3rd_safe.pdf

Code:
template <class T> class Safe {

T* p ; // p points to a T allocated using new
public :
Safe () :p (new T ) { }
~Safe () { delete p ; }
Safe & operator =(const Safe & a) { *p = *a .p ; return *this; }
/ / ...
};
template <class T> class Unsafe { // sloppy and dangerous code
T* p ; // p points to a T
public :
Unsafe (T* pp ) :p (pp ) { }
~Unsafe () { if (!p ->destructible ()) throw E(); delete p; }
Unsafe & operator =(const Unsafe & a)
{
p ->~T (); // destroy old value (§10.4.11)
new (p) T (a .p ); // construct copy of a.p in *p (§10.4.11)
return *this;
}
/ / ...
};

What makes me confused is, the description about why it is not
exception safe,

--------------------
The assignment operator may fail by throwing an exception from T 's
copy constructor. This would
leave a T in an undefined state because the old value of *p was
destroyed and no new value
replaced it.

The critical part is "new (p) T (a .p );" since we do not know what T is
we can not guarantee that constructing an object of type T will succeed
(the most trivial example would be a failure to allocate memory for it).
If that happens the Unsafe object is left in a bad state since we have
already deleted the pointer to the old T object.
BTW: it is also appreciated if you could share some experiences about
what in your minds does invariant status mean

(in Bjarne's minds, exception safety means making the object into
invariant status). I find the word *invariant* is somethings hard to
understand. :)

Invariants are some conditions that always have to be true for an
object. So if we have an object and performs some kind of operation on
it, then those conditions have to be true after the operations were
performed if they also were true before.

In the case above an invariant might be that p must always be a valid
pointer to an object of type T.
 
D

Daniel T.

George2 said:
Hello everyone,


Here is Bjarne's exception safe sample,

http://www.research.att.com/~bs/3rd_safe.pdf

Code:
template <class T> class Safe {

T* p ; // p points to a T allocated using new
public :
Safe () :p (new T ) { }
~Safe () { delete p ; }
Safe & operator =(const Safe & a) { *p = *a .p ; return *this; }
/ / ...
};
template <class T> class Unsafe { // sloppy and dangerous code
T* p ; // p points to a T
public :
Unsafe (T* pp ) :p (pp ) { }
~Unsafe () { if (!p ->destructible ()) throw E(); delete p; }
Unsafe & operator =(const Unsafe & a)
{
p ->~T (); // destroy old value (§10.4.11)
new (p) T (a .p ); // construct copy of a.p in *p (§10.4.11)
return *this;
}
/ / ...
};

What makes me confused is, the description about why it is not
exception safe,

--------------------
The assignment operator may fail by throwing an exception from T 's
copy constructor. This would
leave a T in an undefined state because the old value of *p was
destroyed and no new value
replaced it.

Not Unsafe's copy constructor, but T's copy constructor. If during the
call to Unsafe's op=, T's copy constructor throws an exception, the
object that Unsafe points to will be in an indeterminate state.

(Just as a BTW, neither class above is really safe because they are both
missing appropriate copy constructors.)
BTW: it is also appreciated if you could share some experiences about
what in your minds does invariant status mean

(in Bjarne's minds, exception safety means making the object into
invariant status). I find the word *invariant* is
somethings hard to understand. :)

An invariant of a class is something that is always true about all
objects of that class. One of Safe's invariants is that it always points
to a valid T. Unsafe can't make that claim.

You might want to read (http://citeseer.ist.psu.edu/227598.html) as well.
 
D

Dave Rahardja

: BTW: it is also appreciated if you could share some experiences
: about what in your minds does invariant status mean
:
: (in Bjarne's minds, exception safety means making the object into
: invariant status). I find the word *invariant* is
: somethings hard to understand. :)

In invariant is something that doesn't vary, something that is always
true, like an object being in a valid state.

The JSF-AV coding standard
(http://www.research.att.com/~bs/JSF-AV-rules.pdf) has a good
formalization of what an invariant is:

"A class invariant is a statement-of-fact about a class that must be
true for all stable instances of the class. A class is considered to be
in a stable state immediately after construction, immediately before
destruction, and immediately before and after any remote public method
invocation."

-dr
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top