[英]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();
}
現在:
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.