Reputation: 355
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.
Upvotes: 1
Views: 163
Reputation: 76245
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.
Upvotes: 3