2012-10-30 59 views
1

我想知道stack unwinding的一些知識,並且遇到了this page,它用下面的例子來演示它。 這段cpp代碼如何轉儲?

#include <iostream> 
using namespace std; 

struct E { 
    const char* message; 
    E(const char* arg) : message(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("Exception thrown in try block of main()"); 
    } 
    catch (const char* e) { 
    cout << "Exception: " << e << endl; 
    } 
    catch (...) { 
    cout << "Some exception caught in main()" << endl; 
    } 

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

當我編譯但是它得到了核心轉儲克++ /*clang++*.The輸出如下:

In try block 
In constructor of A 
In constructor of B 
In destructor of B 
In destructor of A 
Call to my_terminate 
已放棄 (核心已轉儲) #core dump 

誰能給我一些提示?

+2

那麼,你的「終止」......沒有終止程序! – avakar

回答

2

答案是在拋出異常時拋出異常。

main()中,構造了一個A實例。然後你拋出一個異常。 之前它被抓到,A::~A被調用,其中引發異常。在同一時間飛行中有兩個例外導致terminate()(或用戶提供的等價物)被調用(默認情況下,它調用abort(),這將丟棄核心。無論哪種方式,程序都無法恢復)。除此之外:這是導致一般最佳實踐規則的原因,在這種規則中,除非您的意思是要殺死程序,否則不得在析構函數中拋出異常。

+0

*導致終止被調用(其中,默認情況下,調用abort(),其中刪除核心*,你沒有看到代碼正確.OP有一個終止處理程序。 –

+0

@Als是的,我做到了。我已經更新了我的評論以反映這一點,但這完全是偶然的。 –

+0

@KazDragon你的意思是即使用'my_terminate()'指定程序也不能恢復? –

0

set_terminate()期望提供給它的功能terminate該程序。

不帶參數並返回void的函數。功能應 不返回終止該方案。 terminate_handler是一個 函數指針類型,不帶參數並返回void。

如果您沒有在提供的函數中退出,set_terminate會在調用您的terminate函數後自動調用abort()。 只需在my_terminate()中添加exit(0);即可避免看到此abort()消息。

+0

那麼我該如何解決這個問題呢? –

+0

C++標準(18.6.3.3)**不會**命令terminate()來終止程序。 –

+0

@Als你讀過我爲什麼引用?從[這裏](http://www.cplusplus.com/reference/std/exception/set_terminate/) – tomahh