Proper Destruction of Class Members when an Exception is Thrown inDestructor

Discussion in 'C++' started by AnonMail2005@gmail.com, Feb 26, 2009.

  1. Guest

    Can someone point me to the specific are of the standard that will
    clarify this issue?
    I have a class that contains at least one other member. If an
    exception is throw in
    the destructor, is that member properly destructed?

    Sample (non-working) code:

    #incude <string>

    class Foo
    {
    public:
    // constructor
    Foo () {}

    // destructor
    ~Foo ()
    {
    // do something here that will throw (e.g. some logging)
    // is the std::string properly destructed?
    }

    private:
    std::string m_s;
    };

    thanks
    , Feb 26, 2009
    #1
    1. Advertising

  2. Leandro Melo Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    On 26 fev, 12:47, "" <>
    wrote:
    > Can someone point me to the specific are of the standard that will
    > clarify this issue?
    > I have a class that contains at least one other member.  If an
    > exception is throw in
    > the destructor, is that member properly destructed?
    >
    > Sample (non-working) code:
    >
    > #incude <string>
    >
    > class Foo
    > {
    > public:
    >   // constructor
    >   Foo () {}
    >
    >   // destructor
    >   ~Foo ()
    >     {
    >       // do something here that will throw (e.g. some logging)
    >       // is the std::string properly destructed?
    >     }
    >
    > private:
    >   std::string m_s;
    >
    > };


    Well, you should start from a very important C++ guideline which says
    that destructors should not throw. Never!

    If you implement a destructor that might throw you'll be unable to
    rely on others well know C++ idioms. Basically, you won't be able to
    write exception-safe code and provide any kind of commit-or-rollback
    guarantee.

    In addition, you'll also be in trouble when using operators like new[]
    and delete[].

    Bottom line: Don't let your destructors throw.

    --
    Leandro T. C. Melo
    Leandro Melo, Feb 26, 2009
    #2
    1. Advertising

  3. Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    On Feb 26, 11:03 am, Leandro Melo <> wrote:
    > On 26 fev, 12:47, "" <>
    > wrote:
    >
    >
    >
    >
    >
    > > Can someone point me to the specific are of the standard that will
    > > clarify this issue?
    > > I have a class that contains at least one other member.  If an
    > > exception is throw in
    > > the destructor, is that member properly destructed?

    >
    > > Sample (non-working) code:

    >
    > > #incude <string>

    >
    > > class Foo
    > > {
    > > public:
    > >   // constructor
    > >   Foo () {}

    >
    > >   // destructor
    > >   ~Foo ()
    > >     {
    > >       // do something here that will throw (e.g. some logging)
    > >       // is the std::string properly destructed?
    > >     }

    >
    > > private:
    > >   std::string m_s;

    >
    > > };

    >
    > Well, you should start from a very important C++ guideline which says
    > that destructors should not throw. Never!
    >
    > If you implement a destructor that might throw you'll be unable to
    > rely on others well know C++ idioms. Basically, you won't be able to
    > write exception-safe code and provide any kind of commit-or-rollback
    > guarantee.
    >
    > In addition, you'll also be in trouble when using operators like new[]
    > and delete[].
    >
    > Bottom line: Don't let your destructors throw.
    >
    > --
    > Leandro T. C. Melo- Hide quoted text -
    >
    > - Show quoted text -


    Never use the word never!
    , Feb 26, 2009
    #3
  4. Daniel Pitts Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    wrote:
    > On Feb 26, 11:03 am, Leandro Melo <> wrote:
    >> On 26 fev, 12:47, "" <>
    >> wrote:
    >>> Can someone point me to the specific are of the standard that will
    >>> clarify this issue?

    >> Well, you should start from a very important C++ guideline which says
    >> that destructors should not throw. Never!
    >>
    >> If you implement a destructor that might throw you'll be unable to
    >> rely on others well know C++ idioms. Basically, you won't be able to
    >> write exception-safe code and provide any kind of commit-or-rollback
    >> guarantee.
    >>
    >> In addition, you'll also be in trouble when using operators like new[]
    >> and delete[].
    >>
    >> Bottom line: Don't let your destructors throw.

    > Never use the word never!

    Except about "Exceptions leaving Destructors"

    The reasoning I've heard is: When an exception is thrown from any part
    of your code, the stack starts to unwind. This includes calling any
    appropriate destructors. If a destructor throws an exception, then what
    is supposed to happen? Does the new exception take precedence? Does the
    old one trump?

    The answer is: I don't care, because it is probably not what I want.
    Don't let your destructor throw an exception.

    Worse case scenario, let the program die immediately.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 26, 2009
    #4
  5. Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    On Feb 26, 12:36 pm, Daniel Pitts
    <> wrote:
    > wrote:
    > > On Feb 26, 11:03 am, Leandro Melo <> wrote:
    > >> On 26 fev, 12:47, "" <>
    > >> wrote:
    > >>> Can someone point me to the specific are of the standard that will
    > >>> clarify this issue?
    > >> Well, you should start from a very important C++ guideline which says
    > >> that destructors should not throw. Never!

    >
    > >> If you implement a destructor that might throw you'll be unable to
    > >> rely on others well know C++ idioms. Basically, you won't be able to
    > >> write exception-safe code and provide any kind of commit-or-rollback
    > >> guarantee.

    >
    > >> In addition, you'll also be in trouble when using operators like new[]
    > >> and delete[].

    >
    > >> Bottom line: Don't let your destructors throw.

    > > Never use the word never!

    >
    > Except about "Exceptions leaving Destructors"
    >
    > The reasoning I've heard is: When an exception is thrown from any part
    > of your code, the stack starts to unwind. This includes calling any
    > appropriate destructors.  If a destructor throws an exception, then what
    > is supposed to happen? Does the new exception take precedence? Does the
    > old one trump?
    >
    > The answer is: I don't care, because it is probably not what I want.
    > Don't let your destructor throw an exception.
    >
    > Worse case scenario, let the program die immediately.
    >
    > --
    > Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>- Hide quoted text -
    >
    > - Show quoted text -


    It is well defined what happens when an exception is thrown during
    stack unwinding, so there is no guessing what will happen.

    I found the portion of the standard that actually *answers* my
    specific question.
    The relevant section is 15.2.2.
    , Feb 26, 2009
    #5
  6. anon Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    wrote:
    > On Feb 26, 12:36 pm, Daniel Pitts
    > <> wrote:
    >> wrote:
    >>> On Feb 26, 11:03 am, Leandro Melo <> wrote:
    >>>> On 26 fev, 12:47, "" <>
    >>>> wrote:
    >>>>> Can someone point me to the specific are of the standard that will
    >>>>> clarify this issue?
    >>>> Well, you should start from a very important C++ guideline which says
    >>>> that destructors should not throw. Never!
    >>>> If you implement a destructor that might throw you'll be unable to
    >>>> rely on others well know C++ idioms. Basically, you won't be able to
    >>>> write exception-safe code and provide any kind of commit-or-rollback
    >>>> guarantee.
    >>>> In addition, you'll also be in trouble when using operators like new[]
    >>>> and delete[].
    >>>> Bottom line: Don't let your destructors throw.
    >>> Never use the word never!

    >> Except about "Exceptions leaving Destructors"
    >>
    >> The reasoning I've heard is: When an exception is thrown from any part
    >> of your code, the stack starts to unwind. This includes calling any
    >> appropriate destructors. If a destructor throws an exception, then what
    >> is supposed to happen? Does the new exception take precedence? Does the
    >> old one trump?
    >>
    >> The answer is: I don't care, because it is probably not what I want.
    >> Don't let your destructor throw an exception.
    >>
    >> Worse case scenario, let the program die immediately.
    >>
    >> --
    >> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > It is well defined what happens when an exception is thrown during
    > stack unwinding, so there is no guessing what will happen.
    >
    > I found the portion of the standard that actually *answers* my
    > specific question.
    > The relevant section is 15.2.2.


    I doubt 15.2.2 is relevant, because in 99.99% an exception thrown from a
    destructor will terminate the process.

    Can not think of an example where 0.01% this is not true.
    anon, Feb 27, 2009
    #6
  7. Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    On Feb 27, 3:30 am, anon <> wrote:
    > wrote:
    > > On Feb 26, 12:36 pm, Daniel Pitts
    > > <> wrote:
    > >> wrote:
    > >>> On Feb 26, 11:03 am, Leandro Melo <> wrote:
    > >>>> On 26 fev, 12:47, "" <>
    > >>>> wrote:
    > >>>>> Can someone point me to the specific are of the standard that will
    > >>>>> clarify this issue?
    > >>>> Well, you should start from a very important C++ guideline which says
    > >>>> that destructors should not throw. Never!
    > >>>> If you implement a destructor that might throw you'll be unable to
    > >>>> rely on others well know C++ idioms. Basically, you won't be able to
    > >>>> write exception-safe code and provide any kind of commit-or-rollback
    > >>>> guarantee.
    > >>>> In addition, you'll also be in trouble when using operators like new[]
    > >>>> and delete[].
    > >>>> Bottom line: Don't let your destructors throw.
    > >>> Never use the word never!
    > >> Except about "Exceptions leaving Destructors"

    >
    > >> The reasoning I've heard is: When an exception is thrown from any part
    > >> of your code, the stack starts to unwind. This includes calling any
    > >> appropriate destructors.  If a destructor throws an exception, then what
    > >> is supposed to happen? Does the new exception take precedence? Does the
    > >> old one trump?

    >
    > >> The answer is: I don't care, because it is probably not what I want.
    > >> Don't let your destructor throw an exception.

    >
    > >> Worse case scenario, let the program die immediately.

    >
    > >> --
    > >> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>- Hide quoted text -

    >
    > >> - Show quoted text -

    >
    > > It is well defined what happens when an exception is thrown during
    > > stack unwinding, so there is no guessing what will happen.

    >
    > > I found the portion of the standard that actually *answers* my
    > > specific question.
    > > The relevant section is 15.2.2.

    >
    > I doubt 15.2.2 is relevant, because in 99.99% an exception thrown from a
    > destructor will terminate the process.
    >
    > Can not think of an example where 0.01% this is not true.- Hide quoted text -
    >
    > - Show quoted text -


    Of course it's relevant because it answered my specific question.

    *******
    15.2.2 says:
    An object that is partially constructed or partially destroyed will
    have destructors executed for all of its fully constructed subobjects,
    that is, for subobjects for which the constructor has completed
    execution and the destructor has not yet begun execution. Should a
    constructor for an element of an automatic array throw an exception,
    only the constructed elements of that array will be destroyed. If the
    object or array was allocated in a new-expression, the matching
    deallocation function (3.7.3.2, 5.3.4, 12.5), if any, is called to
    free the storage occupied by the object.
    ******

    For an exception thrown from a destructor ***during stack
    unwinding***, the *default* action is to terminate the process. So
    that only happens during stack unwinding - i.e. when an exception has
    already been thrown.
    , Feb 27, 2009
    #7
  8. anon Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    wrote:
    >
    > Of course it's relevant because it answered my specific question.
    >
    > *******
    > 15.2.2 says:
    > An object that is partially constructed or partially destroyed will
    > have destructors executed for all of its fully constructed subobjects,
    > that is, for subobjects for which the constructor has completed
    > execution and the destructor has not yet begun execution. Should a
    > constructor for an element of an automatic array throw an exception,
    > only the constructed elements of that array will be destroyed. If the
    > object or array was allocated in a new-expression, the matching
    > deallocation function (3.7.3.2, 5.3.4, 12.5), if any, is called to
    > free the storage occupied by the object.
    > ******
    >
    > For an exception thrown from a destructor ***during stack
    > unwinding***, the *default* action is to terminate the process. So
    > that only happens during stack unwinding - i.e. when an exception has
    > already been thrown.
    >


    Sorry I misunderstood you.

    The answer to your question is : yes, all constructed class members will
    be properly destructed.

    And unless you are doing something like in the following example, your
    process should be properly destructed as well :p

    struct A
    {
    ~A() { throw "hi"; }
    };

    int main()
    {
    try
    {
    A *a = new A;
    try
    {
    delete(a);
    }
    catch(...)
    {
    }
    }
    catch(...)
    {
    }
    }
    anon, Feb 27, 2009
    #8
  9. James Kanze Guest

    Re: Proper Destruction of Class Members when an Exception is Thrownin Destructor

    On Feb 27, 9:30 am, anon <> wrote:
    > wrote:
    > > On Feb 26, 12:36 pm, Daniel Pitts
    > > <> wrote:
    > >> wrote:
    > >>> On Feb 26, 11:03 am, Leandro Melo <> wrote:
    > >>>> On 26 fev, 12:47, "" <>
    > >>>> wrote:
    > >>>>> Can someone point me to the specific are of the standard that will
    > >>>>> clarify this issue?
    > >>>> Well, you should start from a very important C++ guideline which says
    > >>>> that destructors should not throw. Never!
    > >>>> If you implement a destructor that might throw you'll be unable to
    > >>>> rely on others well know C++ idioms. Basically, you won't be able to
    > >>>> write exception-safe code and provide any kind of commit-or-rollback
    > >>>> guarantee.
    > >>>> In addition, you'll also be in trouble when using operators like new[]
    > >>>> and delete[].
    > >>>> Bottom line: Don't let your destructors throw.
    > >>> Never use the word never!
    > >> Except about "Exceptions leaving Destructors"


    > >> The reasoning I've heard is: When an exception is thrown
    > >> from any part of your code, the stack starts to unwind.
    > >> This includes calling any appropriate destructors. If a
    > >> destructor throws an exception, then what is supposed to
    > >> happen? Does the new exception take precedence? Does the
    > >> old one trump?


    > >> The answer is: I don't care, because it is probably not
    > >> what I want. Don't let your destructor throw an exception.


    > >> Worse case scenario, let the program die immediately.


    > > It is well defined what happens when an exception is thrown
    > > during stack unwinding, so there is no guessing what will
    > > happen.


    > > I found the portion of the standard that actually *answers*
    > > my specific question.
    > > The relevant section is 15.2.2.


    > I doubt 15.2.2 is relevant, because in 99.99% an exception
    > thrown from a destructor will terminate the process.


    That's simply false. Most of the time, an exception thrown from
    a destructor will NOT terminate the process.

    > Can not think of an example where 0.01% this is not true.


    class ThrowsInDestructor
    {
    public:
    ~ThrowsInDestructor() { throw 42; }
    } ;

    int
    main()
    {
    try {
    ThrowsInDestructor t ;
    std::cout << "t constucted" << std::endl ;
    } catch ( int i ) {
    return i ;
    }
    return 0 ;
    }

    The problem isn't that most of the time, throwing from a
    destructor will terminate the process. The problem is
    guaranteeing that this will never be the case. Something that
    is very difficult, if not impossible, for most general purpose
    classes (but there exist a very few, special classes, whose sole
    purpose is for the destructor to throw).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 2, 2009
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Selen
    Replies:
    0
    Views:
    2,670
    Selen
    May 28, 2004
  2. =?Utf-8?B?VmFs?=
    Replies:
    0
    Views:
    3,120
    =?Utf-8?B?VmFs?=
    Jun 8, 2005
  3. Fao, Sean
    Replies:
    5
    Views:
    393
    Fao, Sean
    Jul 6, 2003
  4. Dennis Jones
    Replies:
    2
    Views:
    311
    Dennis Jones
    Jan 5, 2007
  5. Replies:
    4
    Views:
    261
    Victor Bazarov
    Feb 20, 2007
Loading...

Share This Page