Thread: Lifetime of temporary during exception throw

  1. #1
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396

    Lifetime of temporary during exception throw

    What does the standard say about this?

    Code:
    class A {};
    
    class Exception
    {
    public:
        Exception( const A &a )
            : value( a )
        {}
    
        const A &value;
    };
    
    void SomeCode()
    {
        throw Exception( A() );
    }
    During the actual throw/catch process itself, is it guaranteed that the lifetime of the temporary A() object will be at least as long as the lifetime of the Exception object? Or is this undefined?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It would be undefined unless the argument provided when creating the exception is static. Otherwise, that object is only guaranteed to exist within the scope it is created so a dangling reference would be received when the execption is caught.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Wow, that's a curve-ball.
    Given a const-reference does extend the lifetime of a temporary to the lifetime of the const-reference I would think that it would have to work, though even the entire function containing the declaration of the temporary is exited, so given that it would surely be a stack-based variable I guess that means it's gone, which would perhaps trump the const-reference lifetime extension rule...

    Yeah I'd be interested to read a direct quote form the standard about it too.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The C++ Standard Section 12.2, para 3 has this to say. Note that I've lost some formatting in copying ....
    3 When an implementation introduces a temporary object of a class that has a nontrivial constructor (12.1), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a nontrivial
    destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception.
    which I suspect trumps subsequent paragraphs that cover (among other things) binding of temporaries to const references.
    4 There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete. The object is initialized from a copy of the temporary; during this copying, an implementation can call the copy constructor many times; the temporary is destroyed after it has been copied, before or when the initialization completes. If many temporaries are created by the evaluation of the initializer, the temporaries are destroyed in reverse order of the completion of their construction.

    5 The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call. A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits. In all these cases, the temporaries created during the evaluation of the expression initializing the reference, except the temporary to which the reference is bound, are destroyed at the end of the fullexpression in which they are created and in the reverse order of the completion of their construction. If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction. In addition, the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static or automatic storage duration (3.7.1, 3.7.2); that is, if obj1 is an object with static or automatic storage duration created before the temporary is created, the temporary shall be destroyed before obj1 is destroyed; if obj2 is an object with static or automatic storage duration created after the temporary is created, the temporary shall be destroyed after obj2 is destroyed. [Example:
    Code:
    class C { // ...
    public:
        C();
        C(int);
        friend C operator+(const C&, const C&);
        ~C();
    };
    
    C obj1;
    const C& cr = C(16)+C(23);
    C obj2;
    the expression C(16)+C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16), a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecified whether T1 or T2 is created first. On an implementation where T1 is created before T2, it is guaranteed that T2 is destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed before obj2, it is guaranteed that obj2 is destroyed before T3, and that T3 is destroyed before obj1. ]
    Of course, there is plenty of room for interpretation or misinterpretation in that lot.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. STL sort throw exception?
    By George2 in forum C++ Programming
    Replies: 11
    Last Post: 01-10-2008, 06:34 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Replies: 5
    Last Post: 06-06-2007, 11:10 PM
  4. Problem with the exception class in MINGW
    By indigo0086 in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2007, 01:12 PM
  5. std::bad_exception don´t throw exception
    By ripper079 in forum C++ Programming
    Replies: 2
    Last Post: 03-20-2003, 07:47 PM