A question regarding throwing an exception
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15

Thread: A question regarding throwing an exception

  1. #1
    Join Date
    Jul 2005
    Posts
    941

    A question regarding throwing an exception

    Here is the code,
    Code:
    class A
    {
        public:
            ~A()
            {
                throw 1;
            }
    };
    
    int main()
    {
        try
        {
            A a;
            throw 2;
        }
        catch(...)
        {
        }
    }
    The program ends up being terminated. Is it because catch(...) couldn't handle two exceptions? Thanks.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,323

    Re: A question regarding throwing an exception

    Read: GotW #47: Uncaught Exceptions. Basically, you should not be throwing an exception from within a destructor.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,997

    Re: A question regarding throwing an exception

    that isn't entirely correct.

    1) you can throw exceptions from a destructor as long as they are caught in that destructor.
    2) the code in your destructor can call other code which can call other code (etc.) that can throw an exception. Which is ok, as long as you catch the exception in the destructor itself.

    You cannot however allow an exception to remain uncaught and try to 'terminate' the destructor. That'll cause all sorts of weird things to happen including summoning the 4 horsemen to end the world as we know it.

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,997

    Re: A question regarding throwing an exception

    Also the GotW#47 is somewhat erroneous.

    There's nothing necessarily wrong in testing std::uncaught_exception() and having an if/else branch depending on the result. It is wrong if you're doing it to decide "is it safe to throw and let the throw escape the destructor", that's just ALWAYS wrong, regardless of the result of uncaught_exception.

    There might be a good reason to do something else in a destructor if there's uncaught exceptions (can't think of anything useful atm). So the initial premise of the gotw is wrong or rather, confusing at least.

    uncaught exceptions originating in the destructor 'escaping' the destructor is bad.

    uncaught exceptions from elsewhere causing stack unwinds and destructors being called is normal case scenario, and testing for such uncaught exceptions in a destructor isn't necessarily wrong or problematic. Whether you can ever do something right/usefull is another matter entirely. I can't think of anything atm, but that doesn't mean there isn't a use.

  5. #5
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,323

    Re: A question regarding throwing an exception

    Quote Originally Posted by OReubens
    1) you can throw exceptions from a destructor as long as they are caught in that destructor.
    True. However, if you are throwing exceptions from a destructor in order to catch it in that destructor, then you are probably misusing exceptions.

    Quote Originally Posted by OReubens
    2) the code in your destructor can call other code which can call other code (etc.) that can throw an exception. Which is ok, as long as you catch the exception in the destructor itself.
    Yes. This is mentioned in the article.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #6
    Join Date
    Jul 2005
    Posts
    941

    Re: A question regarding throwing an exception

    Quote Originally Posted by OReubens View Post
    that isn't entirely correct.

    1) you can throw exceptions from a destructor as long as they are caught in that destructor.
    2) the code in your destructor can call other code which can call other code (etc.) that can throw an exception. Which is ok, as long as you catch the exception in the destructor itself.

    You cannot however allow an exception to remain uncaught and try to 'terminate' the destructor. That'll cause all sorts of weird things to happen including summoning the 4 horsemen to end the world as we know it.
    Basically if an exception is not caught, then the program will be terminated. The statement catch(...) will catch "throw 1" and "throw 2", right? So home come the program is still terminated. Thanks.

  7. #7
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,323

    Re: A question regarding throwing an exception

    Quote Originally Posted by LarryChen
    The statement catch(...) will catch "throw 1" and "throw 2", right? So home come the program is still terminated.
    It only catches the exception thrown at throw 1. When that happens, the destructor is invoked, causing the exception from throw 1 to be thrown and not caught.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,997

    Re: A question regarding throwing an exception

    because it is throwing from the A destructor. You aren't given a means to catch something that is thrown in a destructor, so the throw 1 never arrives in the catch (...) in main.

  9. #9
    Join Date
    Jul 2005
    Posts
    941

    Re: A question regarding throwing an exception

    Quote Originally Posted by OReubens View Post
    because it is throwing from the A destructor. You aren't given a means to catch something that is thrown in a destructor, so the throw 1 never arrives in the catch (...) in main.
    But if I comment out “throw 2", "throw 1" can arrive in the catch(...) in the main. Only if I uncomment out "throw 2", "throw 1" never arrives in the catch(...). Why? Thanks.

  10. #10
    Join Date
    Jul 2005
    Posts
    941

    Re: A question regarding throwing an exception

    Quote Originally Posted by laserlight View Post
    It only catches the exception thrown at throw 1. When that happens, the destructor is invoked, causing the exception from throw 1 to be thrown and not caught.
    I don't quite understand what you said. You said it only catches "throw 1" and then you said "causing the exception from throw 1 to be thrown and not caught". What does that mean? Thanks.

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,323

    Re: A question regarding throwing an exception

    Quote Originally Posted by LarryChen
    But if I comment out “throw 2", "throw 1" can arrive in the catch(...) in the main. Only if I uncomment out "throw 2", "throw 1" never arrives in the catch(...). Why?
    If you comment out the throw 2, then when the lifetime of A ends because it goes out of scope, its destructor is invoked, leading to throw 1, which is then caught.

    Quote Originally Posted by LarryChen
    I don't quite understand what you said. You said it only catches "throw 1" and then you said "causing the exception from throw 1 to be thrown and not caught". What does that mean?
    Sorry, typo error. It should read: It only catches the exception thrown at throw 2. When that happens, the destructor is invoked, causing the exception from throw 1 to be thrown and not caught.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  12. #12
    Join Date
    Oct 2008
    Posts
    1,153

    Re: A question regarding throwing an exception

    Quote Originally Posted by LarryChen View Post
    What does that mean? Thanks.
    let's rephrase it,

    when an exception is thrown, living automatic (ie stack) objects are destroyed in reverse order ( in a process called "stack unwinding" ); if an exception is thrown from a destructor while stack unwinding then std::terminate is invoked.

    Why ? because the language says so
    ok, but why ? stack unwinding it's like an emergency plan for when something goes wrong; in theory, there could be an emergency plan for when even that emergency plan goes wrong, and so on ... so, again in theory, the language could allow multiple stack "unwindings" always allowing to rethrow from a destructor. But, this is probably not allowed because it would be too hard to follow/manage/mantain such failure scenarios ( including an infinite throw-loop ) without any true added benefit.

  13. #13
    Join Date
    Jul 2005
    Posts
    941

    Re: A question regarding throwing an exception

    Quote Originally Posted by superbonzo View Post
    let's rephrase it,

    when an exception is thrown, living automatic (ie stack) objects are destroyed in reverse order ( in a process called "stack unwinding" ); if an exception is thrown from a destructor while stack unwinding then std::terminate is invoked.

    Why ? because the language says so
    ok, but why ? stack unwinding it's like an emergency plan for when something goes wrong; in theory, there could be an emergency plan for when even that emergency plan goes wrong, and so on ... so, again in theory, the language could allow multiple stack "unwindings" always allowing to rethrow from a destructor. But, this is probably not allowed because it would be too hard to follow/manage/mantain such failure scenarios ( including an infinite throw-loop ) without any true added benefit.
    Thanks for your reply. I think I understand it. So what happens in the code is that when "throw 2" is executed, then catch(...) will be called right away and then destroy all the automatic objects from A a until the try statement. So A's destructor will be invoked, but ”throw 1" is not caught. So the program is terminated. So the good practice is that always catch the exception thrown by the destructor within the destructor, right?

  14. #14
    Join Date
    Apr 1999
    Posts
    27,434

    Re: A question regarding throwing an exception

    Quote Originally Posted by LarryChen View Post
    So the good practice is that always catch the exception thrown by the destructor within the destructor, right?
    It isn't just a "good practice". You cannot allow exceptions to leave a destructor, period. Therefore you have no choice but to catch anything before the destructor completes.

  15. #15
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,997

    Re: A question regarding throwing an exception

    Allowing an exception to go uncaught from a destructor is "undefined behaviour" in C++.

    It might seem to work... sometimes, and fail at other times, under different case scenarios.

    What you are seeing is a manifestation of that undefined behaviour.
    Whenever you use something in C++ that is labeled as "undefined", then the results will be undefined, non portable, may fail depending on compiler, compiler settings, operating systems, the time of day, the color of your underwear and what you mom had for breakfast 2 weeks ago.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center