Some code I am responsible for at work recently got exposed to a new environment, and suddenly started logging exceptions. After some investigation, my colleague Thomas and I felt pretty sure what was going on, except the exception we saw in the logs was of a different type than the one that was thrown by the suspected culprit. What was going on, could the error be some place else after all? Then we looked at some intermediate code in the call hierarchy, and found the following (as usual, simplified) code :
class Exception{}; class SpecialException : public Exception {}; try { throw SpecialException(); } catch (Exception e) { cout << "Caught" << typeid(e).name() << endl; }
Spot the problem? catch (Exception e)
results in slicing. We are catching by value, which results in copying the exception. But since we are catching Exception, not SpecialException, Exception‘s copy construcor is called, and we lose the SpecialException part of the object. Here is an illustration of the Exception copy constructor in action:

On the left side is the full SpecialException object, with its Exception part shown in green. The green line illustrates the copy constructor, which only lets the Exception part of the object throuh.
The right way to write this would be catch (const Exception& e)
, which would result in a reference to the original SpecialException. Thanks to polymorphism, this program will now print “Caught SpecialException”, whereas the original example prints “Caught Exception”.
As a side note, always throw by value, not by pointer. That is, do throw Exception();
, not throw new Exception();
. After all, you want to be throwing an exception, not a pointer. And as always, there is no point in allocating on the heap if you don’t have to. Requiring people to clean up memory for you when catching is not very polite.
Thanks for the tip, these make for great reading. :)
One of the best explanation I got, thanks
Hey, great explanation! thanks!
I was wondering – is there a reason not to use a const Exception& e?
Is there a scenario we might modify the data of the thrown exception, so it better not be const?
Good point! I can’t think of a scenario where one would want to modify the exception. I prefer catching by const ref, and have updated the article to suggest that now. Thanks!
Have you ever thought of modifying an exception before rethrowing it? Perhaps if the caller can only partially handle the error and you want it to continue propagating up the stack.
I would then rather create a new exception which includes the relevant information from the previously thrown one.
Honestly I probably would create a new one too, though I wonder if modifying and rethrowing, or the compiler reusing the memory of the old one (considering it to be something similar to an xvalue) would be more efficient.
I guess you could modify the existing exception in place and rethrow that. Then you would avoid the cost of destroying the existing exception, creating a new temporary one, and copying the temporary into the special exception memory. But the cost of that is probably negligible unless you’re using exceptions way too much in the first place.
How does catching by const reference handle scope? You appear to have a reference to a stack variable that just died when the function threw..
Exceptions are not allocated on the stack, specifically to avoid that problem.
Exactly what i was wondering from last 2 hour.
const ref is better as , r-Value also can work , like the temp is always const &
Yes, const ref is indeed what I recommend in the article. You can’t catch by rvalue reference though.