Why You Shouldn’t Throw in Destructors

In my post two weeks ago, What’s the Point of Function Try Blocks, I mentioned that you shouldn’t throw in destructors. Why exactly is this?

Imagine the following:

void f() {
  MyClass c;

If functionThatMightThrow throws, stack unwinding occurs. What this means is basically that all the objects on the stack get destructed, from the innermost block and out. In this case, c is destroyed before the exception is thrown out of f.

But what happens if ~MyClass() throws? There would now be two simultaneously active exceptions, something that luckily is forbidden by the standard. Instead, terminate() is called, and the whole program stops.

So what can you do? Design around it. Log and swallow. Ignore. Abort. If your class is managing some resource that should be cleaned up, but failing to do so is not critical, you could also provide a close() method that throws on error. A client who feels it is necessary to be 100% sure the resource is cleaned up will then have the option of calling close() and handling the exception himself, before your destructor is called.

Note that relying on the client to remember to call close(), setUp(), init() etc. is generally a bad idea, but might be acceptable in some cases. What makes it acceptable in this case is if cleaning up the resource is optional.

One thought on “Why You Shouldn’t Throw in Destructors

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s