CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Handing more than one exception at a time

  1. #1
    Join Date
    Jul 2007
    Posts
    249

    Lightbulb Handing more than one exception at a time

    It is advisable not to throw the exception from destructor. Because if exception happens stack unwinding happens. suppose the destructor again throws the exception then on part of first exception again one exception is thrown and exceptions can not be handled at same time. This is what i read from stack over flow.


    Is it true or my understanding is wrong

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Handing more than one exception at a time

    Not exactly. It's not throwing the exception during stack unwinding that is the problem. The problem is when the exception thrown during stack unwinding is not caught. If you catch any thrown exception within your destructor (that is called during stack unwinding) there is no problem.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

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

    Re: Handing more than one exception at a time

    Quote Originally Posted by Rajesh1978 View Post
    It is advisable not to throw the exception from destructor.
    This statement is wrong or incomplete on 2 different things.

    1) 'advisable' is not strong enough.
    Throwing an exception in a destructor (and not catching it) is "undefined behaviour". And thus a flagrant bug.
    If you do it anyway, and it happens during a stack unwind. the app will get terminated right there and then.


    2) I've seen many people fail to realise that it's not about throwing from the destructor.
    but it's about "allowing an exception to 'escape' from the destructor"

    It's perfectly possible to throw an exception and catch it in the destructor
    and it's a bug to call other code that throws and not catch it. (I've even seen people attempting to circumvent this issue by "hiding" the throw in a call.

    so
    Code:
    int FuncThatCouldThrow(int i)
    {
         if (i<100)
             throw i;
         else
             return i*5;
    }
    
    class Foo
    {
    public:
       ~Foo()
       {
          // This is perfectly fine
          try
          {
              FuncThatCouldThrow(myval); // Could throw an int depending on myval
              throw (int)1;                         // throw anyway
          }
          catch (int e)
          {
               // I caught an int with value e !   we're safe now.
          }
    
          // This is debatably faulty (if you assume it won't throw, it'll work fine)
          FuncThatCouldThrow(9001); 
    
          // These are bugs
          FuncThatCouldThrow(42);
          throw "catch me if you can";
       }
    
       int myval;
    };
    Last edited by OReubens; February 13th, 2015 at 08:18 AM.

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Handing more than one exception at a time

    Quote Originally Posted by OReubens View Post
    Throwing an exception in a destructor (and not catching it) is "undefined behaviour". And thus a flagrant bug.
    Wait what? since when? That's news to me. Are you sure about this? AFAIK, you just *shouldn't* throw exceptions in destructors. Do you have any references for that?

    If you do it anyway, and it happens during a stack unwind. the app will get terminated right there and then.[/QUOTE]

    The "if you do it anyways ... then" kind of contradicts what "undefined behavior" is.

    In any case, this trivial test case contradicts it:
    Code:
    #include <iostream>
    #include <stdexcept>
    
    struct S {
        ~S() {
            throw std::runtime_error("Oh noes!");
        }
    };
    
    int main()
    {
        try {
            S s;
        } catch (std::runtime_error&) {
            std::cout << "here" << std::endl;
        }
    }
    Note: I do not advocate throwing exceptions in destructors.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

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

    Re: Handing more than one exception at a time

    Quote Originally Posted by monarch_dodra
    In any case, this trivial test case contradicts it:
    The problem of course is that a test case behaving as you expect does not contradict OReubens' claim of undefined behaviour since the behaviour that you expect falls within the realm of undefined behaviour. That said, you are right to say that the behaviour is well defined:
    Quote Originally Posted by C++11 Clause 15.2 Paragraph 3
    The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called "stack unwinding." If a destructor called during stack unwinding exits with an exception, std::terminate is called (15.5.1). [ Note: So destructors should generally catch exceptions and not let them propagate out of the destructor. — end note ]
    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
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Handing more than one exception at a time

    Quote Originally Posted by laserlight View Post
    The problem of course is that a test case behaving as you expect does not contradict OReubens' claim of undefined behaviour since the behaviour that you expect falls within the realm of undefined behaviour. That said, you are right to say that the behaviour is well defined:
    Yes, it did not disprove the UB. It did disprove the "If you do it anyways, it terminates". Which was kind of my point that both statements are contradictory (you can't have UB if the standard specifies a deterministic consequence).
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,144

    Re: Handing more than one exception at a time

    According to Stroustrup (The c++ Programming Language), Terminate() relating to a destructor is called when (13.5.2.5)
    - a destructor invoked during stack unwinding tries to exit with a throw
    - a destructor for a statically allocated or thread-local object tries to exit with a throw

    It also states (13.7 [30]) that you should never let an exception escape from a destructor. Also 13.2 says that violating a standard-library requirement such as having a destructor exit by throwing an exception is logically equivalent to violating a fundamental language rule. The practical effects are often disastrous.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.6.3)

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Handing more than one exception at a time

    Quote Originally Posted by monarch_dodra View Post
    Yes, it did not disprove the UB. It did disprove the "If you do it anyways, it terminates". Which was kind of my point that both statements are contradictory (you can't have UB if the standard specifies a deterministic consequence).
    if you want it more in detail...

    throwing from a destructor DURING stack unwind (i.e. already handling an exception) will terminate the app.

    if you do it while no unwind is busy, then... "what do you expect will happen" ?
    is the destruction complete and do you have a properly destructed object ? (how could it possibly have completed past the throw ?)
    or did the destruction not complete and do you now have partially existing objects still roaming around somewhere ? (this is a bug by my book)
    this is what I meant with "undefined behaviour", there's no behaviour that will be guaranteed to work the same on all the C++ compilers.

  9. #9
    Join Date
    Jul 2007
    Posts
    249

    Re: Handing more than one exception at a time

    Very good knowledge is being exchanged.
    Thanks to all gurus

    Now my real question is repeated
    throwing from a destructor DURING stack unwind (i.e. already handling an exception) will terminate the app.
    I meant the above quoted thing in the beginning.

    question is why two exceptions can not be handled. ( one being thrown from other exception handling process)

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Handing more than one exception at a time

    Quote Originally Posted by Rajesh1978 View Post
    question is why two exceptions can not be handled. ( one being thrown from other exception handling process)
    because the compiler can't resolve this.

    You throw an exception
    the compiler starts to unwind the stack up to the matching catch.

    on it's way there, you throw a new exception.
    should the runtime process your new exception ? and if so how far should it unwind the stack in order to do so ? (and what happens with the old exception ?) which "catch" wins ?
    or should it continue the unwind and... then ... ???? do something ? with that second exception. meanwhile code was running with an unhandled exception pending which could have all kinds of nasties.


    It's like me tying your left hand on your back and throwing a ball to you. You can catch the ball, but what are you doing to do if I throw another ball at you. you either drop the first ball and catch the second, or you ignore the 2nd ball and han gon to the first.
    Whicheve way you pick, you dropped a ball. The runtime has no "safe" option other than terminating your app.

  11. #11
    Join Date
    Jul 2007
    Posts
    249

    Re: Handing more than one exception at a time

    Thanks. Now i undersood

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




On-Demand Webinars (sponsored)