編輯:從角度來看,提出這個問題的另一種方法是問:Lippincott 函式是否應該“抓住所有”?
是否應該宣告Lippincott 函式noexcept?這有關系嗎?
畢竟,根據定義,捕獲所有例外的此函式版本不能產生例外。
但是,在我在網上看到的所有示例中,noexcept從來沒有出現過,我想知道我是否遺漏了什么。
示例案例:
foo_Result lippincott() noexcept???
{
try {
throw;
} catch (const MyException1&) {
return FOO_ERROR1;
} catch (const MyException2&) {
return FOO_ERROR2;
} catch (...) {
return FOO_UNKNOWN;
}
}
foo_Result foo_dothing() {
try {
foo::DoThing();
return FOO_OK;
}
catch (...) {
return lippincott();
}
}
uj5u.com熱心網友回復:
并非所有catch (...)執行都來自 C 例外。通常建議在任何 catch-all 塊中重新引發例外。這意味著它lippincott不應該是 noexcept 并且也沒有catch-all 塊。
具體來說,在 Windows 之外 C 常用的 ABI 中,強制展開可能會執行 catch-all 塊:
在強制展開期間可能會執行 catch-all 塊。例如,longjmp 可能在堆疊展開期間執行 catch(...) 中的代碼。但是,如果發生這種情況,無論是否有明確的重新拋出,都將在 catch-all 塊的末尾進行展開。
特別是,使用 Linux 上的 GCC,塊被執行,如果不重新拋出,應用程式被終止。如果您呼叫取消點(例如read),即使在您在 POSIX 上完全控制的代碼中也可能發生強制展開。
除此之外,庫執行用戶代碼(例如 think qsort)并不少見。您通常也不想抑制這些例外。
因此,最好的通用選項是在包羅萬象的塊中保持透明。執行所需的清理。然后總是重新拋出。
所以你的函式看起來像:
foo_Result lippincott()
{
try {
throw;
} catch (const MyException1&) {
return FOO_ERROR1;
} catch (const MyException2&) {
return FOO_ERROR2;
} catch (const FooBaseException&) {
return FOO_UNKNOWN;
}
}
GCC 確實允許捕獲強制展開,所以如果你真的想要一個包羅萬象并且放棄其他考慮因素(例如沒有用戶回呼),你可以先 catchabi::__forced_unwind和 rethrow。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/426269.html
