Thread: exception handling, function call and memory

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


    Sorry I missed this reply from you after reviewing this thread again. :-)

    (1) I think you mean even if we do stack unwinding at first, there is still something left on the current stack of the function, like return address?

    (2) Then exception handler will be called.

    So, the conclusion is stack will continue to grow because of (1). Maybe also because of (2), caller will push something on stack? I missed something in assembly language about how function call is implemented in details. :-)

    Quote Originally Posted by matsp View Post
    My comment was to clarify your question on CornedBee's 1,2,3 ordering, and I agree with CornedBee that it happens in the order described.

    But the stack will possibly, temporarily, grow when performing exception handling BEFORE it shrinks. In the example given in the #1 post here, there will be no (large) stack reduction, because the throw does not lead to leaving the function, so there is no other stack-frame to remove.

    --
    Mats

    regards,
    George

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by George2 View Post
    I think your above comments mean the same thing -- which I also agree -- during stack unwinding, not all of the stack of the current function which throw happens will disappear, but a part of them will be on the stack -- the part before the try block and in my sample may include return address of the client of the function, right?
    Yes, everything in the try block, including function calls, objects and other variables will be destroyed, poped or just disappear, because they go out of scope. Everything before the try block will remain intact.
    A way to look at exceptions is this:
    For each function, the compiler will use a "return" statement, so the local variables are poped, destructors are called, etc, until it reaches the function that handles the exception. There it will jump to the catch handler and that means everything in the try block goes out of scope, so variables are poped and destructors are called.

    Another interesting question is, if in try block we invoked another function? How do we restore the state?
    You don't.

    Code:
    void Help2(int& n)
    {
    	n = 7;
    	throw 1;
    }
    
    void Help()
    {
    	int n = 0;
    	try
    	{
    		Help2(n);
    	}
    	catch(...)
    	{
    		cout << n << endl;
    	}
    }
    In the catch block, n will be 7.
    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. #18
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Elysia,


    Great! My question is answered.

    Quote Originally Posted by Elysia View Post
    Yes, everything in the try block, including function calls, objects and other variables will be destroyed, poped or just disappear, because they go out of scope. Everything before the try block will remain intact.
    A way to look at exceptions is this:
    For each function, the compiler will use a "return" statement, so the local variables are poped, destructors are called, etc, until it reaches the function that handles the exception. There it will jump to the catch handler and that means everything in the try block goes out of scope, so variables are poped and destructors are called.



    You don't.

    Code:
    void Help2(int& n)
    {
    	n = 7;
    	throw 1;
    }
    
    void Help()
    {
    	int n = 0;
    	try
    	{
    		Help2(n);
    	}
    	catch(...)
    	{
    		cout << n << endl;
    	}
    }
    In the catch block, n will be 7.

    regards,
    George

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by George2 View Post
    Another interesting question is, if in try block we invoked another function? How do we restore the state?

    Sample code,

    Code:
    void foo()
    {
        FooClass function_local_object;
        manipulate_data (&function_local_object);
        try{
        goo (&function_local_object); // modify function_local_object
        throw(something);
        } catch (...)
        {
        }
    }
    How to restore the status of function_local_object to the exact state after calling manipulate_data (&function_local_object)?

    (saving a copy is memory storage expensive solution.)


    thanks in advance,
    George
    There are several ways you can achieve this, but all involve storing some "undo-data". If it's hard/expensive to store the entire object [e.g. the object represents the current document of several megabytes in your word processor], then you can store "what changes are being made", and then undo those steps as appropriate in the catch phase.

    An alternative process is to do prepare and commit - so you prepare a set of changes, and once you know that everything is OK (no exceptions) you "commit" your list of changes to the object - it's the same principle as the undo list, but the other way around.

    Neither of these are trivial solutions, and "recovering to previously known good state" is not an easy problem to solve, ever.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    I agree your undo and commit solutions.

    1.

    The point we discussed here is compiler or runtime during stack unwinding never helps to restore the state of function_local_object) just after manipulate_data (&function_local_object) is called. We have to do such things (like you mentioned undo and commit) by ourselves.

    2.

    Undo and commit may both expensive.

    Quote Originally Posted by matsp View Post
    There are several ways you can achieve this, but all involve storing some "undo-data". If it's hard/expensive to store the entire object [e.g. the object represents the current document of several megabytes in your word processor], then you can store "what changes are being made", and then undo those steps as appropriate in the catch phase.

    An alternative process is to do prepare and commit - so you prepare a set of changes, and once you know that everything is OK (no exceptions) you "commit" your list of changes to the object - it's the same principle as the undo list, but the other way around.

    Neither of these are trivial solutions, and "recovering to previously known good state" is not an easy problem to solve, ever.

    --
    Mats

    regards,
    George

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Correct, the exception handling does not restore objects to the state before the try (or any other state), the object will be in whatever state it happens to be when the exception is thrown, and it's up to the application code to make sure that this state is consistent with whatever rules the application and the user expects it to follow.

    Yes, any form of undo/commit or copying of objects will involve "extra work" - so it will have a cost applied to it. But if that's what you need, then you must do that. If it's not necessary, then it is of course wasted effort.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    My question is answered. I am happy that from you I not only answered myself the original question, but also learning extra things. Cool!!

    Quote Originally Posted by matsp View Post
    Correct, the exception handling does not restore objects to the state before the try (or any other state), the object will be in whatever state it happens to be when the exception is thrown, and it's up to the application code to make sure that this state is consistent with whatever rules the application and the user expects it to follow.

    Yes, any form of undo/commit or copying of objects will involve "extra work" - so it will have a cost applied to it. But if that's what you need, then you must do that. If it's not necessary, then it is of course wasted effort.

    --
    Mats

    have a good day,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM
  5. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM