Exception Handling Confusion

Consider the following program

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

class E {
   public:
      const char* error;
      E(const char* arg) : error(arg) { }
};

void my_terminate() {
  cout << "Call to my_terminate" << endl;
}

struct A {
  A() { cout << "In constructor of A" << endl; }
  ~A(){
    cout << "In destructor of A" << endl;
    throw E("Exception thrown in ~A()");
  }
};

struct B {
  B() { cout << "In constructor of B" << endl; }
  ~B() { cout << "In destructor of B" << endl; }
};

int main() {

  set_terminate(my_terminate);

  try {
    cout << "In try block" << endl;
    A a;
    B b;
    throw E("Exception thrown in try block of main()"); // Line 36
  }
  catch (E& e) {
    cout << "Exception: " << e.error << endl;
  }
  catch (...) {
    cout << "Some exception caught in main()" << endl;
  }

  cout << "Resume execution of main()" << endl;

}

Output:

In try block
In constructor of A
In constructor of B
In destructor of B
In destructor of A
Call to my_terminate

Disallowed system call: SYS_kill

On line 36, the exception is thrown from the try block in main. Now why did this exception not get into the handler?

Rather, the process of "unwinding the stack" continues. Destructor A also throws an exception that is not caught again by any handler; instead, a call is made my_terminate, why?

Why is the handler not called in two cases?

+3
source share
5 answers

E try main, E catch, . catch (E& e).

catch , , , , throw , catch.

a b, catch, , ( , ). a . catch , , . , std::terminate, , .

, my_terminate terminate_handler, terminate_handler return (.. throw)). .

+3

set_terminate

term_func , . set_terminate ++ , . . , set_terminate . terminate , set_terminate. ,

term_func .

( ), .

my_terminate() :

void my_terminate() 
{
  cout << "Call to my_terminate" << endl;
  *
  *
  *
  exit(-1);

}
+1

15.2 :

3 , try throw-expression "" ". [: , std:: terminate (15.5.1). . -end note]

" " , , , , . , , , .

0

. , . , . . , , , . E. , ? , , terminate(). , std::set_terminate() <exception>.

, std::terminate() , , undefined.
, :

uncaught_exception() <exception> true, , . true, , , , . , , , .

Here is an example of how to use it (although this is a very bad idea): uncaught_exception()

#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
#include <cstdlib>

void termhandler()
{
    std::cout << "Inside terminate()" << std::endl;
    abort();
}

class Foo
{
public:
    Foo(int val) : i(val){ std::cout << "Created Foo object " << i << std::endl; }
    ~Foo()
    {
        if(std::uncaught_exception()){
            std::cout << "~Foo::Foo() object " << i << " : " << "Stack unwinding in progress. Can't throw!" << std::endl;
        } else {
            std::cout << "~Foo::Foo() object " << i << " : " << "Throwing test exception." << std::endl;
            std::ostringstream strm;
            strm << i;
            std::runtime_error e("Exception from ~Foo::Foo() object " + strm.str());
            throw e;
        }
    }
    int i;
};

int main()
{
    try {
        std::set_terminate(termhandler);    
        Foo A(1);
        Foo B(2);
    } catch(std::exception& e){
        std::cout << "Caught exception in main() : " << e.what() << std::endl;
    }
}

Which gives the following conclusion:

Foo 1
object created. Foo 2 created object.
~ Foo :: Foo () object 2: test poll exception.
~ Foo :: Foo () object 1: The stack is being rotated. I can not quit!
Fixed exception in main (): Exception from object ~ Foo :: Foo () 2

0
source

Source: https://habr.com/ru/post/1718627/


All Articles