Home > Mobile >  How function-level exception handling works?
How function-level exception handling works?

Time:12-20

There is the following code, from here

class Base {
    int i;
public:
    class BaseExcept {};
    Base(int i) : i(i) { throw BaseExcept(); }
};
class Derived : public Base {
public:
    class DerivedExcept {
        const char* msg;
    public:
        DerivedExcept(const char* msg) : msg(msg) {}
        const char* what() const { return msg; }
    };
    Derived(int j) try : Base(j) {  
        // Constructor body
        cout << "This won't print" << endl;
    }
    catch (BaseExcept&) {
        throw DerivedExcept("Base subobject threw");;
    }
};
int main() {
    try {
        Derived d(3);
    }
    catch (Derived::DerivedExcept& d) {
        cout << d.what() << endl;  // "Base subobject threw"
    }
}

My question is, why the thrown exception is not caught here

catch (BaseExcept&) {
throw DerivedExcept("Base subobject threw");;
}

But the catch in main?

catch (Derived::DerivedExcept& d) {
cout << d.what() << endl; // "Base subobject threw"
}

Why does it output "Base subobject threw"

According to my understanding, the thrown exception should be caught in the catch after try (or the function body equivalent to try), but there is no, why? What is the propagation path of the exception?

code from there

My question is this, try catch I have seen before all have this form.

try{}
catch(){}

So I think for the following snippet

     Derived(int j) try: Base(j) {
         // Constructor body
         cout << "This won't print" << endl;
     }
     catch (BaseExcept&) {
         throw DerivedExcept("Base subobject threw");;
     }

When Derived() throws an exception, it should be caught by the catch (BaseExcept&)in the following line, not by the catch (Derived::DerivedExcept& d) in the main function. But when I comment out it here

     catch (Derived::DerivedExcept& d) {
         //cout << d.what() << endl; // "Base subobject threw"
     }

There will be no "Base subobject threw" output. This is different from what I expected. I am learning basic exception knowledge. Did I understand something wrong

CodePudding user response:

Derived(int j) try : Base(j) {  
        // Constructor body
        cout << "This won't print" << endl;
    }
    catch (BaseExcept&) {      // why the thrown exception is not caught here
        throw DerivedExcept("Base subobject threw");;
    }

The only way for the program to output Base subobject threw is if the exception is actually caught where you do not think it's caught. The string does not exist anywhere else in the program.

But the catch in main?

That's because you throw an exception in the catch. That exception is not caught by the same catch (which would result in infinite recursion in this case). It's caught by the outer try..catch which you have in main.

  • Related