Thread: life cycle of exception object

Hybrid View

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

    life cycle of exception object

    Hello everyone,


    1.

    Suppose I have code like this. According to the standard, the storage of exception object is undefined (could be either on stack or on heap?).

    2.

    I am wondering what is the life cycle of the exception object which reference variable e binded to? For example, could we bind a global reference to the exception object referred by e? Or doing something on the exception object beyond the bracket?

    3.

    The life cycle of variable e itself should not beyond the bracket, right?

    Code:
    catch (exception& e)
    {
        // ...
    }

    thanks in advance,
    George

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    1) The storage of the exception object can be anywhere. Technically, doing "throw x;" where x is some object or value, then x ceases to exist when control passes out of the scope in which it was created. For example;
    Code:
    void f()
    {
          {
               SomeType x;
               throw x;
          }
          //   x does not exist here
    }
    While x ceases to exist as soon as control is returned to an enclosing scope, a temporary copy of x exists until the exception is caught (or the program terminates due to an uncaught exception) -- and will be copied repeatedly as control passes to enclosing scopes. Then compiler implementation details kick in, as the standard explicitly allows (as opposed to "requires") the compiler to avoid creating a temporary if the only way of detecting that temporary is by tracking constructor and destructor calls.

    2) and 3) The reference e exists until control leaves the scope of the catch block, as does the object e refers to. If the catch block rethrows the exception then, logically, a copy of the exception object will be created, and copied during stack unwinding. Practically, again, the compiler is allowed to be smarter than that, so it can avoid creating copies.

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


    Suppose in catch block we pass the address of the exception object to a global pointer variable or make a global reference variable binded to the exception object (let me know if I have not made myself understood). And after catch block or even after function returns, is it safe to access the global reference variable or the global pointer variable?

    Quote Originally Posted by grumpy View Post
    1) The storage of the exception object can be anywhere. Technically, doing "throw x;" where x is some object or value, then x ceases to exist when control passes out of the scope in which it was created. For example;
    Code:
    void f()
    {
          {
               SomeType x;
               throw x;
          }
          //   x does not exist here
    }
    While x ceases to exist as soon as control is returned to an enclosing scope, a temporary copy of x exists until the exception is caught (or the program terminates due to an uncaught exception) -- and will be copied repeatedly as control passes to enclosing scopes. Then compiler implementation details kick in, as the standard explicitly allows (as opposed to "requires") the compiler to avoid creating a temporary if the only way of detecting that temporary is by tracking constructor and destructor calls.

    2) and 3) The reference e exists until control leaves the scope of the catch block, as does the object e refers to. If the catch block rethrows the exception then, logically, a copy of the exception object will be created, and copied during stack unwinding. Practically, again, the compiler is allowed to be smarter than that, so it can avoid creating copies.

    regards,
    George

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That would equivalent of taking a reference/address of a local variable in any other context, so no, this is not valid and leads to undefined behaviour.

    --
    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. #5
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    I have written some code which verified that the caught object instance is not the original one we thrown. Looks like we only get a temporary exception object in catch block?

    Here is my code. You can see two object instance is created.

    Code:
    #include <iostream>
    
    using namespace std;
    
    class Foo {
    public:
    	Foo(int input)
    	{
    		this->a = input;
    		cout << this << endl;
    	}
    
    	Foo (const Foo& input)
    	{
    		this->a = input.a;
    		cout << this << endl;
    	}
    	int a;
    };
    
    void foo()
    {
    	try {
    		Foo* f = new Foo (100);
    		throw *f;
    	} catch (const Foo& e)
    	{
    		cout << e.a << endl;
    	}
    }
    
    int main()
    {
    	foo();
    }
    Quote Originally Posted by matsp View Post
    That would equivalent of taking a reference/address of a local variable in any other context, so no, this is not valid and leads to undefined behaviour.

    --
    Mats

    regards,
    George

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, like Grumpy said, it's a temporary copy of the original object - the original object may even be destroyed by the time the catch is entered.

    --
    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. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Your conclusions are wholly unnecessary.

    1) They might be the same.
    2) No, it might be merged with the exception object.
    3) Of course not.


    One addition to what grumpy said: a re-throw does not create a new exception object.
    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

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


    Can you show me some pseudo code for (1) and (2) please?

    Quote Originally Posted by CornedBee View Post
    Your conclusions are wholly unnecessary.

    1) They might be the same.
    2) No, it might be merged with the exception object.
    3) Of course not.


    One addition to what grumpy said: a re-throw does not create a new exception object.

    regards,
    George

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Can you show me some pseudo code for (1) and (2) please?
    No, it's a compiler optimization.
    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
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi CornedBee,


    I can understand the exception object in try and in catch may share the same object instance for compiler optimization purpose.

    But what do you mean (2) -- "No, it might be merged with the exception object.". What do you mean merged?

    Quote Originally Posted by CornedBee View Post
    No, it's a compiler optimization.

    regards,
    George

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It means that if the compiler can clearly see that there is no need to copy the object - such as the throw and the object are within the same scope as the catch, then there is no need to copy the object, and the compiler doesn't do that. Just like the compiler can "omit" reading the same data twice if it knows that it hasn't changed. [Unless you tell it that the data is volatile].

    --
    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.

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


    I think the conclusion of this thread is quite flexible. :-)

    1. The objct instance in try block may be the same as the one in try block, may be not. Dependent on compiler's optimization;

    2. Safe to use the object instance in the catch block. But not safe to use it outside catch block.

    Does I missed anything important as our conclusion?

    Quote Originally Posted by matsp View Post
    It means that if the compiler can clearly see that there is no need to copy the object - such as the throw and the object are within the same scope as the catch, then there is no need to copy the object, and the compiler doesn't do that. Just like the compiler can "omit" reading the same data twice if it knows that it hasn't changed. [Unless you tell it that the data is volatile].

    --
    Mats

    regards,
    George
    Last edited by George2; 02-04-2008 at 08:56 AM.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    2) Er, what? It's definitely safe to use the exception object in the catch block.
    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

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm with CornedBee on this. However, the result of using a pointer, pointing to the exception object within the catch block, after leaving the catch block is DEFINITELY not OK.

    --
    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.

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


    I agree with you and CornedBee. It is my typo before.

    About my conclusion in post #17, do you think I missed anything important?

    Quote Originally Posted by matsp View Post
    I'm with CornedBee on this. However, the result of using a pointer, pointing to the exception object within the catch block, after leaving the catch block is DEFINITELY not OK.

    --
    Mats

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Telling a shared_ptr not to delete object?
    By TriKri in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2008, 04:26 AM
  2. circular doubly linked list help
    By gunnerz in forum C++ Programming
    Replies: 5
    Last Post: 04-28-2007, 08:38 PM
  3. Problem with the exception class in MINGW
    By indigo0086 in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2007, 01:12 PM
  4. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  5. Life, The Universe, and everything else
    By ZooTrigger1191 in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 03-29-2003, 05:33 PM