Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a safe way of throwing an exception from a destructor?

I know that throwing from a destructor is in general a bad idea, but I was wondering if i could use std::uncaught_exception() to safely throw from a destructor.

Consider the following RAII type:

struct RAIIType {
   ...

   ~RAIIType() {
      //do stuff..
      if (SomethingBadHappened()) {
           //Assume that if an exception is already active, we don't really need to detect this error
           if (!std::uncaught_exception()) {
               throw std::runtime_error("Data corrupted");
           }
      }
   }
};

Is this UB in c++11? Is it a bad design?

like image 866
sbabbi Avatar asked Mar 21 '13 16:03

sbabbi


People also ask

Can we throw an exception from the destructor?

The C++ rule is that you must never throw an exception from a destructor that is being called during the "stack unwinding" process of another exception. For example, if someone says throw Foo(), the stack will be unwound so all the stack frames between the throw Foo() and the } catch (Foo e) { will get popped.

Can I throw an exception from a constructor from a destructor?

When an exception is thrown from a constructor, the object is not considered instantiated, and therefore its destructor will not be called. But all destructors of already successfully constructed base and member objects of the same master object will be called.

Which technique is used to handle a destructor that fails?

A failure in the constructor can be handled by throwing an exception, where as throwing an exception in the destructor will lead to stack unwinding.

What happens if an exception is throws from an object's constructor and object's destructor?

Destructors are only called for the completely constructed objects. When the constructor of an object throws an exception, the destructor for that object is not called.


1 Answers

You have an if, did you think about the "other" condition? It can throw an exception or... do what? There's two things that can be in the other branch.

  • Nothing (If nothing needs to happen when the error occurs, why throw an exception?)
  • It "handles" the exception (If it can be "handled", why throw an exception?)

Now that we've established that there's no purpose to throwing an exception conditionally like that, the rest of the question is sort of moot. But here's a tidbit: NEVER THROW EXCEPTIONS FROM DESTRUCTORS. If an object throws an exception, the calling code normally checks that object in some way to "handle" the exception. If that object no longer exists, there's usually no way to "handle" the exception, meaning the exception should not be thrown. Either it's ignored, or the program makes a dump file and aborts. So throwing exceptions from destructors is pointless anyway, because catching it is pointless. With this is mind, classes assume that destructors won't throw, and virtually every class leaks resources if a destructor throws. So NEVER THROW EXCEPTIONS FROM DESTRUCTORS.

like image 147
Mooing Duck Avatar answered Oct 15 '22 16:10

Mooing Duck