Search code examples
c++exceptionerror-handlingtry-catchthrow

What happens if a thrown value matches several catch clauses?


Literally what happens if one value thrown does match several catch clauses?

The compiler decides it or it makes errors?

The following is an example with one value thrown and that matches three catch clauses.

I compile it and get errors. But don't know what that error means...

    #include <iostream>
    using namespace std;

    class AAA
    {
    public:
        void ShowYou() { cout<<"AAA exception!"<<endl; }
    };

    class BBB : public AAA
    {
    public:
        void ShowYou() { cout<<"BBB exception!"<<endl; }
    };

    class CCC : public BBB
    {
    public:
        void ShowYou() { cout<<"CCC exception!"<<endl; }
    };

    void ExceptionGenerator(int expn)
    {
        if(expn==1)
            throw AAA();
        else if(expn==2)
            throw BBB();
        else
            throw CCC();
    }

    int main(void)
    {
        try
        {
            ExceptionGenerator(1);
            ExceptionGenerator(1);
            ExceptionGenerator(1);
        }

        catch(AAA& expn)
        {
            cout<<"catch(AAA& expn)"<<endl;
            expn.ShowYou();
        }   

        catch(AAA& expn)
        {
            cout<<"catch(BBB& expn)"<<endl;
            expn.ShowYou();
        }

        catch(AAA& expn)
        {
              cout<<"catch(CCC& expn)"<<endl;
              expn.ShowYou();
        }
      system("pause"); return 0;
}

Error 1 error C2312: 'AAA &' : is caught by 'AAA &' on line 40

I get the error above.

What does it mean by that?


Solution

  • From n3337 standard draft, 15.3/4

    4 The handlers for a try block are tried in order of appearance. That makes it possible to write handlers that can never be executed, for example by placing a handler for a derived class after a handler for a corresponding base class.

    This means that the second and third catch block are basically unreachable code. Still, your program is well-formed and a conforming compiler shouldn't reject it (mine just emits warnings, for example).

    When you have an exception hierarchy, make them behave polymorphicaly to distinguish between them:

    #include <iostream>
    using namespace std;
    
    class AAA {
    public:
        virtual void ShowYou() { cout<<"AAA exception!"<<endl; }
    };
    
    class BBB : public AAA {
    public:
        void ShowYou() { cout<<"BBB exception!"<<endl; }
    };
    
    class CCC : public BBB {
    public:
        void ShowYou() { cout<<"CCC exception!"<<endl; }
    };
    
    void ExceptionGenerator()
    {
        int expn = 0;
        cin >> expn;
        if(expn==1)
            throw AAA();
        else if(expn==2)
            throw BBB();
        else
            throw CCC();
    }
    
    int main(void)
    {
        try
        {
            ExceptionGenerator();
        }
        catch(AAA& expn)
        {
            expn.ShowYou();
        }
    
        system("pause"); return 0;
    }