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

Barbara Streisand
Lepaskan: 2024-11-01 01:29:02
asal
376 orang telah melayarinya

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>
Salin selepas log masuk

Output Jangkaan:

exception: outer : abcd
exception:  inner : abcdabcd
exception:   really_inner
exception:    too long
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!