简体   繁体   中英

exception handling, unexpected terminator in c++

Following code is about exception handling. I got the output:

Botch::f()
I'll be back!

Why Fruit is not caught? Thanks!

Ignore this. I think I have provided enough detail.

#include <exception>
#include <iostream>
using namespace std;

void terminator() {
    cout << "I'll be back!" << endl;
    exit(0);
}

void (*old_terminate)() = set_terminate(terminator);

class Fruit {};

class Botch {
public:
    void f() throw(Fruit, bad_exception) {
        cout << "Botch::f()" << endl;
        throw Fruit();
    }
    ~Botch() { throw 'c'; }
};

int main() {
    try{
        Botch b;
        b.f();
    } catch(Fruit&) {
        cout << "inside catch(Fruit)" << endl;
    } catch(bad_exception&) {
        cout << "caught a bad_excpetionfrom f" << endl;
    }
}

Because during stack unwinding for your Fruit exception you threw another exception (from the Botch destructor). So your terminator was called instead. This is why throwing exceptions from a destructor is a bad idea,

Fruit is not caught because the code never reaches that catch clause. In the try block in main , the call to bf() throws an exception of type Fruit . In response, the code destroys the Botch object before entering the catch clause. The destructor of Botch throws another exception, and that triggers the call to terminate .

When bf() is called in main, a Fruit is thrown. Then execution leaves the try block, and before any catch handler can catch that Fruit , b is destroyed and 'c' is thrown. Throwing a second exception while the Fruit is still active leads to termination, regardless of any catch handlers.
This is the reason why you never shall throw from destructors.

because the program flow is as follows:

try{
        Botch b;
        b.f();
        //-> exception of class Fruit has been thrown
        //-> Stack unwinding: during stack unwinding object b, 
        //which is on stack is destroyed, and its destructor is called
        //-> this destructor ~Botch() { throw 'c'; } throws another exception 
        //and this caused call of your terminator()
    } catch(Fruit&) {  // so we are never here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM