If you use exceptions to signal errors in C++, you should be really careful when throwing an exception from inside a class' destroyer function, because you can easily cause an abort trap. Consider the following code:

struct test {
~test(void) {
throw int(0);
}
};

int main(void) {
try {
test t;
throw int(1);
} catch (int e) {
} catch (...) {
}

return 0;
}

Trivial, isn't it? Well, now compile it and run it: you will get a "nice" core dump. However, if you disable the throw statement inside ~test, the problem will go away. The problem will also disappear if you move test's instantiation outside the try block.

But... why does this happen? When the int(1) exception is thrown, the t object has to be destroyed before it can be handled, because its scope has to be cleaned (see how it's placed inside the try block). When this happens, the destroyer function throws a new exception (while we were handling another one), which could produce an infinite loop. Voila, you've got the abort trap.

So be aware when throwing an exception from a destroyer. Simply put, you must make sure that they will not generate exceptions; you have to handle any possible failure from within them.

Go to posts index

Comments from the original Blogger-hosted post: