Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a exception object destroyed (and can it be controlled)?

Tags:

c++

I'm writing a drop-replacement for a container, and I'm trying to get all the exception-guarantees in place. I'm currently writing the clear method, and I want it to complete as much as possible, and to always leave the container in a consistent state, even if one of the destructors throw an exception. I also want to rethrow the exception after I'm done cleaning, preferably without slicing.

This brings me to the question; when is an exception destructed? Lets have a look at one attempt: This is simplified for the example.

void container::clear()
{
    bool had_exception = false;
    std::exception* exp;
    internal_set_empty(); // this cant throw
    while( ! internal_done() )
    {
        try
        {
            internal_destruct_next(); // this might throw if T::~T() throws
        }
        catch( std::exception& e )
        {
            had_exception = true;
            exp = &e;
        }
    }
    if( had_exception )
        throw *exp;
}

I expect this to fail badly, because the exception is probably destructed when it is considered handled, and this doesn't technically rethrow.

Another attempt would be taking a copy of the exception, something that I expect would slice.

Is there a way to extend the lifetime of the exception so I can rethrow it later? If possible, I would also like to be able to rethrow exceptions caught via catch(...) .

like image 686
sp2danny Avatar asked Aug 20 '15 15:08

sp2danny


People also ask

What happens when an exception is thrown in a destructor?

Throwing an exception out of a destructor is dangerous. If another exception is already propagating the application will terminate.

What is object destroy problem how can Exception handling help here give an example?

Exception handling and object destruction in C++ Destructors in C++ basically called when objects will get destroyed and release memory from the system. When an exception is thrown in the class, the destructor is called automatically before the catch block gets executed.

When an object is destroyed or goes out of scope which function?

Using destructors Destructors are called when one of the following events occurs: A local (automatic) object with block scope goes out of scope. An object allocated using the new operator is explicitly deallocated using delete . The lifetime of a temporary object ends.


1 Answers

even if one of the destructors throw an exception

Cannot be done. Destructors are nothrow for a reason- you can't recover from a throwing destructor. It's clear that you don't do anything to clean up the objects whose destructor threw- because how could you even try to do that- but that also means that you've just left them hanging around in a zombie state.

On your more specific question, you could use recursion to stay inside the catch's stack frame to try to keep deleting elements, or you could also use std::exception_ptr and friends in C++11 which are intended for transporting exceptions around.

like image 83
Puppy Avatar answered Oct 24 '22 18:10

Puppy