Heim  >  Artikel  >  Backend-Entwicklung  >  Warum verwendet C keine verschachtelten Ausnahmen, um von Destruktoren ausgelöste Ausnahmen zu behandeln?

Warum verwendet C keine verschachtelten Ausnahmen, um von Destruktoren ausgelöste Ausnahmen zu behandeln?

Barbara Streisand
Barbara StreisandOriginal
2024-11-01 01:29:02377Durchsuche

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

Warum verwendet C keine verschachtelten Ausnahmen zum Auslösen von Destruktoren?

Verstehen des Problems

Auslösen von Ausnahmen von Destruktoren führt zu einem Dilemma: Was ist zu tun, wenn eine Ausnahme bereits im Gange ist? Mögliche Lösungen sind das Überschreiben der vorhandenen Ausnahme oder das Verschachteln der neuen Ausnahme innerhalb der vorhandenen Ausnahme. Es wurde jedoch entschieden, dass die Beendigung mit std::terminate der Standardansatz wäre.

Berücksichtigung verschachtelter Ausnahmen

C 11 führte die Funktion std::nested_Exception ein, die das Problem möglicherweise beheben könnte, indem die alte Ausnahme in der neuen verschachtelt wird. Diese Idee wurde jedoch nicht umgesetzt.

Gründe für die Nichtimplementierung

Ein Grund dafür, in diesem Zusammenhang keine verschachtelten Ausnahmen zu verwenden, ist die Tatsache, dass std::nested_Exception dies getan hat Sehr eingeschränkte Verwendung, mit nur einer bekannten praktischen Anwendung: Erstellen vollständig kommentierter Aufrufstapel.

Dieses Beispiel zeigt, wie das Verschachteln von Ausnahmen eine bequeme Möglichkeit bietet, Kontext hinzuzufügen und Fehler beim Debuggen zu lokalisieren:

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

Erwartete Ausgabe:

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

Das obige Beispiel zeigt die Verschachtelung von Ausnahmen und zeigt, wie diese Technik dabei hilft, Fehler zu verfolgen und Aufrufstapel zu verstehen.

Trotz der Nützlichkeit verschachtelter Ausnahmen in diesem Fall In einem bestimmten Szenario wurde die Entscheidung, sie nicht im Zusammenhang mit Destruktorausnahmen zu verwenden, wahrscheinlich aufgrund der Einfachheit und Zuverlässigkeit der Beendigung mit std::terminate getroffen.

Das obige ist der detaillierte Inhalt vonWarum verwendet C keine verschachtelten Ausnahmen, um von Destruktoren ausgelöste Ausnahmen zu behandeln?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn