簡體   English   中英

堆棧是否有c ++標准保證的異常展開?

[英]Is stack unwinding with exceptions guaranteed by c++ standard?

關於堆棧展開,c ++標准說:

在完成異常對象([except.throw])的初始化之后,異常被認為是未捕獲的,直到完成異常處理程序的激活([except.handle])。 這包括堆棧展開。

按當前標准的15.5.3 我試圖理解最新句子( This includes stack unwindings )是指什么:

  • 假設編譯器必須負責展開堆棧嗎?
  • 或者,它是說依賴於編譯器是否放松堆棧?

問題來自以下片段:

#include <iostream>
#include <exception>

struct S{
    S() { std::cout << " S constructor" << std::endl; }
    virtual ~S() { std::cout << " S destructor" << std::endl; }
};

void f() {
    try{throw(0);}
    catch(...){}
}

void g() {
    throw(10);
}

int main() {
    S s;
    f();
    //g();
}

現在:

  1. 如果按原樣運行(捕獲異常),則會顯示堆棧展開的提示
  2. 如果你評論f(); 並取消注釋g(); (沒有捕獲異常),你有一堆堆棧沒有被解開

所以,這兩個實驗似乎贊成上面的第一個子彈; clang ++和g ++都同意結果(但它不是判別式)。

此外,在我看來,非常奇怪的是標准,在指定對象的實時時間持續 時間時非常小心,這里留下了陰影。

願有人澄清嗎? 堆棧是否為標准保證的未捕獲異常展開? 如果是的話,在哪里? 如果沒有,為什么?

堆棧是否為標准保證的未捕獲異常展開?

保證堆棧展開僅針對捕獲的異常([except.handle] / 9):

如果找不到匹配的處理程序,則調用函數std::terminate() ; 在對std::terminate()調用是否為實現定義之前,是否展開堆棧。

所以它是實現定義的,否則。

如果沒有,為什么?

如果發生未捕獲的異常,標准會導致調用std::terminate 這表示程序執行的結束。 如果您有一些特定於平台的方法來記錄當時系統狀態的信息,您可能不希望該狀態受到堆棧展開的干擾。

如果你沒有這樣做......那你就不在乎。

如果你真的需要總是解開堆棧,那么你可以把你的main代碼(和任何線程函數)放在try {} catch(...) {throw;}塊中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM