Benjamin Larsen Benjamin Larsen - 1 month ago 10
C++ Question

Exceptions C++: Catch by reference/value

I have a question regarding catching exceptions in C++.
Consider the following example, where we're catching by value:

struct baseException{};
struct derivedException : public baseException {};

void g(){
// Bad stuff

if(!stuff)
throw derivedException();
else
throw baseException();
}

void f(){
try{
g();
}
catch(derivedException e){
// Caught derived exc
}
catch(baseException){
// Caught base exc
}
}


Let's say that
baseException
is thrown. Wouldn't the compiler see that
derivedException
is a specialization of
baseException
, and therefore choose the more correct catch clause (
baseException
)?

I would agree that, if
derivedException
is thrown, and the catch clause order was reversed, slicing would happen, but I'm not really sure what would happen in this case. Why can't the compiler see it as a specialization?

I do agree it's the wrong way, and you should always catch by reference to conserve polymorphicic properties, but I'd like to know why compiler can't recognize the specialization.

Answer

The rule for catch clauses is that the first match is the one that's selected. Unlike overloaded functions, there is no notion of "best" match.

So in the example code, if stuff is false, the body for catch(derivedException) would be executed, because the thrown exception has type derivedException; if stuff is true, the body for catch(baseException) would be executed because the first catch clause doesn't match, but the second one does..

If the catch clauses were reversed, then regardless of the value of stuff, the body of the first catch clause (catch(baseException)) would be executed, because both exceptions can be caught by the base type.