Try as you might…

I came across a corner of C++ exception handling that I had never noticed before (yes, the title is a pun), and it was interesting enough that I thought I’d share.

The issue revolves around the type of an exception after it has been re-thrown. There are two ways to re-throw an exception after it has been caught, throwing by name:
throw e;
and simply throwing the active exception:

I had assumed that they were functionally equivalent, and for most purposes they are. However, in my case I was doing the following:

  • Throwing a specific boost::exception subclass
  • Catching by boost::exception reference
  • Modifying the caught exception (appending some error_info)
  • Re-throwing by name
  • Attempting to catch the re-thrown exception by subclass type

The last step was failing: I was unable to catch the re-thrown exception by subclass type. I discovered, though, that I could catch by subclass type if I did a simple re-throw. It was as if re-throwing by name was stripping type information off of the exception.

And, in fact, that’s exactly what happens. To make a long story short, re-throwing by name constructs a new exception of the static type of the caught exception and throws that copy. This copy is in a magical, implementation-defined memory area.

For a more detailed explanation of what’s going on, check out and

Finally, here’s a bit of code showing the issue. Modifying the argument to try_() will change the re-throw method, and, at least on the compilers I’ve tried (g++-4-somethings on linux), you either catch by Subtype (expected) or Exception (not expected):

#include <exception>
#include <iostream>

using namespace std;

class Exception : public exception {};

class Subtype : public Exception {};

void try_(bool cause_unexpected)
    try { throw Subtype(); }
    catch (const Exception& e) {
        if (cause_unexpected)
            throw e;

int main(void)
    try { try_(false); }
    catch (const Subtype&) {
        cout << "expected" << endl;
    catch (const Exception&) {
        cout << "not expected" << endl;

    return 0;


  1. Leave a comment

Leave a Reply

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

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: