Bjarne's exception safe sample

This is a discussion on Bjarne's exception safe sample within the C++ Programming forums, part of the General Programming Boards category; 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 ; // ...

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    Bjarne's exception safe sample

    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

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,768
    Quote Originally Posted by George2 View Post
    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 (&#167;10.4.11)
    		new (p) T (a .p ); // construct copy of a.p in *p (&#167;10.4.11)
    		return *this;
    	}
    	/ / ...
    };
    Next time, try indenting the code you copy. I know it's indented in the book and it looks like a real mess, pretty unreadable otherwise.

    In my study, I can not find a case why there is exception thrown from Unsafe's copy constructor. Any ideas?
    The copy constructor calls the destructor which throws and exception if the object can't deleted.
    Bjorne is referring to that the object's state might not be "valid," because the class failed with something and didn't fix the problem, didn't clean up.
    So next time some member function is called, the results might be undefined because of the "invalid" state of the class.
    Last edited by Elysia; 12-23-2007 at 05:13 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    2
    i can't answer the question but in general the term invariant in programming and algorithms is used to declare a "state"... for example in a loop that increments a variable the invariant would be that the variable is incremented each time...

    for a more complex example lets say you have this:
    Code:
    while( a condition )
    {
          //do action1
          //do action2
          //do action3
          //etc....
    }
    so each time that you run the whole loop you have an invariant.... if for a strange reason you exit in the middle of action2 you don't have an invariant....{or more correctly you break the invariant...}

    So deducting from the above {but i am not sure the deduction is correct} i would have to say that invariant status of an object is when the final object is created and every temporary memory is freed...

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,338
    >> In my study, I can not find a case why there is exception thrown from Unsafe's copy constructor. Any ideas?

    There is no Unsafe copy constructor shown in that code. Did you mean T's copy constructor or did you mean Unsafe's copy assignment operator?

    As Stroustrup's explanation states, the Unsafe copy assigment operator can throw an exception if T's copy constructor throws an exception.

    To see an example of a class T that throws an exception from it's copy constructor, just make one. T is any type, so if you can create a type that falls under that situation then you've found an example. Sometimes a class will throw an exception from a constructor (including a copy constructor) if the class fails to initialize properly, so it's certainly possible that it will happen. If it does, then Unsafe will be left in a bad state.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Chapter 51. Destructors, deallocation, and swap never fail
    If a destructor called during stack unwinding exits with an exception, terminate is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor. [C++03] §15.2(3)

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks for your analysis, Daved!


    My question is answered.

    Quote Originally Posted by Daved View Post
    >> In my study, I can not find a case why there is exception thrown from Unsafe's copy constructor. Any ideas?

    There is no Unsafe copy constructor shown in that code. Did you mean T's copy constructor or did you mean Unsafe's copy assignment operator?

    As Stroustrup's explanation states, the Unsafe copy assigment operator can throw an exception if T's copy constructor throws an exception.

    To see an example of a class T that throws an exception from it's copy constructor, just make one. T is any type, so if you can create a type that falls under that situation then you've found an example. Sometimes a class will throw an exception from a constructor (including a copy constructor) if the class fails to initialize properly, so it's certainly possible that it will happen. If it does, then Unsafe will be left in a bad state.

    regards,
    George

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Good sample, thanks aegis!


    Quote Originally Posted by aegis View Post
    i can't answer the question but in general the term invariant in programming and algorithms is used to declare a "state"... for example in a loop that increments a variable the invariant would be that the variable is incremented each time...

    for a more complex example lets say you have this:
    Code:
    while( a condition )
    {
          //do action1
          //do action2
          //do action3
          //etc....
    }
    so each time that you run the whole loop you have an invariant.... if for a strange reason you exit in the middle of action2 you don't have an invariant....{or more correctly you break the invariant...}

    So deducting from the above {but i am not sure the deduction is correct} i would have to say that invariant status of an object is when the final object is created and every temporary memory is freed...

    regards,
    George

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi cpjust,


    Does the link has anything to do with my original question? :-)


    regards,
    George

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    I think Bjarne means the copy constructor of T throws exception, other than the destructor of Unsafe class. :-)

    Quote Originally Posted by Elysia View Post
    The copy constructor calls the destructor which throws and exception if the object can't deleted.
    Bjorne is referring to that the object's state might not be "valid," because the class failed with something and didn't fix the problem, didn't clean up.
    So next time some member function is called, the results might be undefined because of the "invalid" state of the class.

    regards,
    George

  10. #10
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,768
    You know you can edit your posts instead of replying 4 times in a row? There's even a multi-quote button.
    Yes, the copy constructor can throw an exception and so can the destructor, because the copy constructor calls the destructor which is the source which might throw the exception.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    Confused. There are two classes, Unsafe and T.

    1. do you mean Unsafe's copy constructor will throw exception or T's constructor will throw exception?

    2. do you mean Unsafe's destructor will throw exception or T's destructor will throw exception?

    Quote Originally Posted by Elysia View Post
    You know you can edit your posts instead of replying 4 times in a row? There's even a multi-quote button.
    Yes, the copy constructor can throw an exception and so can the destructor, because the copy constructor calls the destructor which is the source which might throw the exception.

    regards,
    George

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,768
    Only Unsafe throws exceptions. Both the copy constructor and the destructor of Unsafe can throw exceptions (because the copy constructor calls the destructor which can throw an exception).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Elysia,


    Quote Originally Posted by Elysia View Post
    Only Unsafe throws exceptions. Both the copy constructor and the destructor of Unsafe can throw exceptions (because the copy constructor calls the destructor which can throw an exception).
    I have re-read the book. Yes, you are correct. I agree.


    regards,
    George

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by George2 View Post
    Hi cpjust,

    Does the link has anything to do with my original question? :-)
    Yes. The Unsafe class throws an exception in the destructor:
    Code:
    ˜Unsafe () { if (!p ->destructible ()) throw E(); delete p; }
    If you re-read that link, you'll see why you should never allow an exception to be thrown in a destructor.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exception handling in a large project
    By EVOEx in forum C++ Programming
    Replies: 7
    Last Post: 01-25-2009, 06:33 AM
  2. exception handling
    By coletek in forum C++ Programming
    Replies: 2
    Last Post: 01-12-2009, 04:28 PM
  3. Bjarne's member function binding sample is wrong?
    By George2 in forum C++ Programming
    Replies: 9
    Last Post: 03-11-2008, 04:05 AM
  4. Bjarne's comments about exception specification
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 01-21-2008, 06:51 AM
  5. using swap to make assignment operator exception safe
    By George2 in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2008, 05:32 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21