Benjamin Larsen
Benjamin Larsen

Reputation: 355

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.

Upvotes: 1

Views: 163

Answers (1)

Pete Becker
Pete Becker

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

Related Questions