Nuances of exception rethrow

When you throw an exception, the thrown object is copied to a special location in the memory. Now, suppose you wanted to catch an exception (by reference ofcourse), alter it slightly, and then rethrow it with hope that the same object would be rethrown. The language provides two ways to do just that, which are very different in what they actually do below the surface.

The two possible ways of rethrowing a caught exception are hereby presented:

#include <iostream>

struct E {
    E () {}
    E (const E &e) { std::cout << "x"; }
};

void f () {
    try {
        throw E();
    }
    catch (E &e) {
        throw; // option 1
        throw e; // option 2
    }
}

int main () {
    f();
    return 0;
}

At first glance, one would expect the two options to function essentially in the same way. But what happens is as follows:

  • Using option 1, the very same exception object e is propagated further (rethrown).
    • Obviously enough, there is no invocation of the copy constructor.
  • Using option 2, the received object e is actually copied, and that new copied object is the one that gets propagated further (rethrown).
    • Commenting out the line containing option 1, you would get the ‘x’ char printed by E’s copy constructor.

This difference is an important one, and should be kept in mind when encountering such a situation.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>