Exception in Destructor C++

前端 未结 2 1819
清歌不尽
清歌不尽 2021-02-05 01:24

I am well aware of the fact that one should not throw any exception in destructor.

But as a part of making my grip on this concept,I coded this example :-



        
相关标签:
2条回答
  • 2021-02-05 01:48

    std::terminate will be called if an exception is thrown during stack unwinding. That means that if an exception is called while another exception is being handled, then std::terminate will be called.

    In your example, that doesn't happen - A(); will construct and immediately destroy an instance of A. The throw 30 will then be caught correctly.

    Changing your code to:

    int main(){
        try{
            A a;      // begin `a` lifetime 
            throw 10; // | throw #0           
                      // | end `a` lifetime   
                      // throw #1
        }
        catch(int i){
            cout<<i<<endl;
            cout<<"exception caught"<<endl;
        }
    }
    

    will guarantee that std::terminate will be called. In this case, a will be destroyed and will throw while another exception is being handled.

    live coliru example


    Additional information:

    • cppreference/Destructors/Exceptions

    • StackOverflow: "throwing exceptions out of a destructor"


    Note that in C++11 and above, your code snippet will call std::terminate and provide you a warning:

    main.cpp: In destructor ‘A::~A()’:

    main.cpp:16:15: warning: throw will always call terminate() [-Wterminate]

         throw 30;
    
               ^~
    

    main.cpp:16:15: note: in C++11 destructors default to noexcept

    terminate called after throwing an instance of 'int'

    bash: line 7: 1505 Aborted (core dumped) ./a.out

    As seen in the compiler output, since C++11 destructors are implicitly noexcept(true). If you want to prevent this behavior, you can simply mark them as noexcept(false). Example:

    ~A() noexcept(false)
    {
        throw 30;
    }
    

    live example on coliru

    0 讨论(0)
  • 2021-02-05 01:58

    In your example, A() construct a temporary variable for A then destructs it immediately. Thus throw 10; is never executed.

    The throw statement taking place is in the destructor for A. When executing A::~A(), the program is not unwinding (i.e. cleaning up state from an exception) at that point. See "Destructors that throw" for example.

    0 讨论(0)
提交回复
热议问题