Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa C tidak menggunakan pengecualian bersarang untuk mengendalikan pengecualian yang dilemparkan daripada pemusnah?

Mengapa C tidak menggunakan pengecualian bersarang untuk mengendalikan pengecualian yang dilemparkan daripada pemusnah?

Barbara Streisand
Barbara Streisandasal
2024-11-01 01:29:02377semak imbas

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

Mengapa C tidak menggunakan pengecualian bersarang untuk membuang daripada pemusnah?

Memahami Isu

Melemparkan pengecualian daripada pemusnah memperkenalkan dilema: apa yang perlu dilakukan apabila pengecualian sudah dalam penerbangan? Menimpa pengecualian sedia ada atau menyarangkan pengecualian baharu dalam pengecualian sedia ada merupakan penyelesaian yang berpotensi, tetapi telah diputuskan bahawa penamatan dengan std::terminate akan menjadi pendekatan standard.

Pertimbangan Pengecualian Bersarang

C 11 memperkenalkan ciri std::nested_exception, yang berpotensi menangani isu dengan meletakkan pengecualian lama dalam yang baharu. Walau bagaimanapun, idea ini tidak dilaksanakan.

Sebab Tidak Pelaksanaan

Satu sebab untuk tidak menggunakan pengecualian bersarang dalam konteks ini ialah hakikat bahawa std::nested_exception mempunyai penggunaan yang sangat terhad, dengan hanya satu aplikasi praktikal yang diketahui: mencipta tindanan panggilan beranotasi sepenuhnya.

Contoh ini menunjukkan cara pengecualian bersarang menyediakan cara yang mudah untuk menambah konteks dan menentukan ralat semasa penyahpepijatan:

<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>

Output Jangkaan:

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

Contoh di atas mempamerkan sarang pengecualian dan menunjukkan cara teknik ini membantu dalam mengesan ralat dan memahami susunan panggilan.

Walaupun kegunaan pengecualian bersarang dalam ini senario tertentu, keputusan untuk tidak menggunakannya dalam konteks pengecualian pemusnah berkemungkinan dibuat disebabkan oleh kemudahan dan kebolehpercayaan penamatan dengan std::terminate.

Atas ialah kandungan terperinci Mengapa C tidak menggunakan pengecualian bersarang untuk mengendalikan pengecualian yang dilemparkan daripada pemusnah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn