首頁  >  文章  >  後端開發  >  為什麼 C 不使用巢狀異常來處理析構函數拋出的異常?

為什麼 C 不使用巢狀異常來處理析構函數拋出的異常?

Barbara Streisand
Barbara Streisand原創
2024-11-01 01:29:02380瀏覽

Why doesn't C   use nested exceptions to handle exceptions thrown from destructors?

為什麼 C 不使用巢狀異常從析構函數拋出異常?

理解問題

從析構函數拋出異常引入了一個困境:當異常已經發生時該怎麼辦?覆蓋現有異常或在現有異常中嵌套新異常是潛在的解決方案,但我們決定使用 std::terminate 終止將是標準方法。

考慮巢狀異常

C 11 引入了 std::nested_exception 功能,該功能可以透過將舊異常嵌套在新異常中來解決該問題。然而,這個想法並沒有實現。

未實現的原因

在此上下文中不使用嵌套異常的一個原因是std::nested_exception 具有用途非常有限,只有一個已知的實際應用:建立完全註解的呼叫堆疊。

此範例示範了巢狀異常如何提供一種在偵錯期間新增情境和找出錯誤的便利方法:

<code class="cpp">#include <iostream>
#include <sstream>
#include <exception>

void rethrow(const std::string& context, ...) {
    std::ostringstream ss;
    ss << context;
    auto sep = " : ";
    (void) ((ss << sep << args), sep = ", ", 0)...);
    try {
        std::rethrow_exception(std::current_exception());
    } catch(const std::invalid_argument& e) {
        std::throw_with_nested(std::invalid_argument(ss.str()));
    } catch(const std::logic_error& e) {
        std::throw_with_nested(std::logic_error(ss.str()));
    } catch(...) {
        std::throw_with_nested(std::runtime_error(ss.str()));
    }
}

int main() {
    try {
        outer("xyz");
        outer("abcd");
    } catch(std::exception& e) {
        print_exception(e);
    }
    return 0;
}

void print_exception(const std::exception& e, std::size_t depth = 0) {
    std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n';
    try {
        std::rethrow_if_nested(e);
    } catch (const std::exception& nested) {
        print_exception(nested, depth + 1);
    }
}</code>

預期輸出:

exception: outer : abcd
exception:  inner : abcdabcd
exception:   really_inner
exception:    too long

上面的範例展示了異常的嵌套,並演示了該技術如何幫助追蹤錯誤和理解呼叫堆疊。

儘管在此範例中巢狀異常很有用在特定場景中,由於使用 std::terminate 終止的簡便性和可靠性,可能會決定不在析構函數異常的情況下使用它們。

以上是為什麼 C 不使用巢狀異常來處理析構函數拋出的異常?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn