Thread: Stack unwinding

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

    Stack unwinding

    Hello everyone,


    I listed for scenarios. I think case 1, 2 and 4 are object's destructor is called during stack unwinding caused by exception. Scenario 3 is not stack unwinding and it is normal function return (not exception) triggers the destructor of the object.

    Scenario 1:

    Code:
    try{
        local object defined;
        exception throws;
    } catch ()
    {
        catched;
    }
    Scenario 2:

    Code:
    try{
        local object defined;
        exception throws;
    } catch ()
    {
        not catched;
    }
    Scenario 3:

    Code:
        local object defined;
    try{
        exception throws;
    } catch ()
    {
        catched;
    }
    Scenario 4:

    Code:
        local object defined;
    try{
        exception throws;
    } catch ()
    {
        not catched;
    }

    thanks in advance,
    George

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think the simple rule is that local objects are destructed when they leave scope - one way or another.

    In example 3, unless the catch block rethrows, the local object does not indeed exit its scope within that snippet.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I don't think this example has much to do with exceptions. It's just simple object scope. Normal variables declared inside a set of braces are deleted once they reach the matching closing brace.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    However, if the exception is never caught, the program will crash.
    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.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Elysia View Post
    However, if the exception is never caught, the program will crash.
    Is "Crash" the right term to use when your stack completely unwinds because of an uncaught exception? It certainly looks like a crash, but there must be a different term for it?

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    How about "abort"? I think abort() gets called anyway for the default uncaught exception handler . . . . Or "terminate". Or "die".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Terminate gets, called. The default termination behavior is to call abort, but it is possible to change that.

    Crash is not the term for it, since the behavior is perfectly defined, and sometimes desirable. For example, there may be no reasonable way to handle a bad_alloc exception, so the right thing to do is just kill the terminate.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I wonder if it is in the standard, but I seem to recall it mentioned, that if an exception is uncaught, the destruction of local obects is not guaranteed?

    Actually MingW doesn't output "~A()" for this code (or is it wrong?), so there might be more in George2's question.

    Code:
    #include <iostream>
    
    struct A
    {
        A() {std::cout << "A()\n"; }
        ~A() { std::cout << "~A()\n"; }
    };
    
    int main()
    {
        A a;
        throw 1;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That's correct, anon. It's implementation-defined whether the stack is actually unwound for an uncaught exception.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Thanks. So the fix is to do a catch-all on the highest level?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, since exceptions can be caught at any level, the compiler needs to unwind the stack until a catch is encountered, does it not?
    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.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No. There are many possible implementations of exception handling. One possible implementation would have a separate try block stack. Every time the program enters a try block, information about the catchers of this block is pushed on this stack. Every time an object is created, information about its destructor is pushed on this stack, or perhaps yet another stack. When an exception is thrown, this stack is searched for a handler. If none is found, the program terminates. If an appropriate handler is found, the program then uses the destructor information to destruct objects that need it. Finally, it restores the state of the registers and jumps directly to the catch block.

    Not a very efficient way, but good when the machine can have unexpected stack content. In particular, this method works when you call back and forth between C++ and a language that uses the stack very differently. It's also good if you have rather a lot of RAM but very little space for programs, because other unwinding methods need a lot of static information. This method uses more dynamic information.

    Anyway, it's definitely possible.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

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


    Great reply!

    Two more comments,

    1.

    Quote Originally Posted by CornedBee View Post
    If an appropriate handler is found, the program then uses the destructor information to destruct objects that need it. Finally, it restores the state of the registers and jumps directly to the catch block.
    So invoking destructor before invoking catch handler, right?

    2.

    Quote Originally Posted by CornedBee View Post
    Not a very efficient way, but good when the machine can have unexpected stack content. In particular, this method works when you call back and forth between C++ and a language that uses the stack very differently. It's also good if you have rather a lot of RAM but very little space for programs, because other unwinding methods need a lot of static information. This method uses more dynamic information.
    What do you mean "good when the machine can have unexpected stack content"?


    regards,
    George

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by George2 View Post
    So invoking destructor before invoking catch handler, right?
    Yes, that part is required by the standard. By the time the catch handler is entered, the stack must have been unwound.

    What do you mean "good when the machine can have unexpected stack content"?
    Not all computers have hardware support for the stack. On such systems, a language like C++ might emulate this by some other means. And a different language might emulate it differently. If you then add calls back and forth between the two languages, the stack will look strange, and it won't really be possible to trace execution through it.

    You have to remember that C and C++ were designed to be implementable on very esoteric systems. Thus, in many cases the exact behaviour is left to the implementation even when it seems completely obvious how it's to be done.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks for your description, CornedBee!


    My question is answered.

    Quote Originally Posted by CornedBee View Post
    Yes, that part is required by the standard. By the time the catch handler is entered, the stack must have been unwound.


    Not all computers have hardware support for the stack. On such systems, a language like C++ might emulate this by some other means. And a different language might emulate it differently. If you then add calls back and forth between the two languages, the stack will look strange, and it won't really be possible to trace execution through it.

    You have to remember that C and C++ were designed to be implementable on very esoteric systems. Thus, in many cases the exact behaviour is left to the implementation even when it seems completely obvious how it's to be done.

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stack and pointer problem
    By ramaadhitia in forum C Programming
    Replies: 2
    Last Post: 09-11-2006, 11:41 PM
  2. Question about a stack using array of pointers
    By Ricochet in forum C++ Programming
    Replies: 6
    Last Post: 11-17-2003, 10:12 PM
  3. error trying to compile stack program
    By KristTlove in forum C++ Programming
    Replies: 2
    Last Post: 11-03-2003, 06:27 PM
  4. What am I doing wrong, stack?
    By TeenyTig in forum C Programming
    Replies: 2
    Last Post: 05-27-2002, 02:12 PM
  5. Stack Program Here
    By Troll_King in forum C Programming
    Replies: 7
    Last Post: 10-15-2001, 05:36 PM