2013-07-29 5 views
5

In C 11 dieser ++ ist veraltet: Warum verursacht die "dynamische Ausnahme" -Garantie einen Overhead?

void foo() noexcept; 

In this article von

void foo() throw(); 

und ersetzt wird erklärt, dass der Grund für diese (unter anderem, dass einkochen auf die gleiche Sache) ist das

C++ - Ausnahmespezifikationen werden zur Laufzeit und nicht zur Kompilierzeit überprüft, so dass sie kein Programmierer garantieren, dass alle Ausnahmen behandelt wurden.

Während dieser Sinn für mich macht, ich verstehe nicht, warum throw() dynamisch an erster Stelle geprüft wurde, oder warum noexcept keine Ausnahme Garantie ausgenommen bieten std::terminate anstelle der normalen Stapel Aufruf Abwickeln (was nicht der Fall ist wirklich eine solide Garantie IMO).

Wäre es nicht möglich zu überprüfen, ob während der Kompilierzeit Exceptions ausgelöst werden oder nicht und die Kompilierung fehlschlägt, wenn dies geschieht? Wie ich es sehe, gibt es grundsätzlich drei Fälle:

void foo() noexcept 
{ 
    // 1. Trivial case 
    throw myexcept(); 

    // 2. Try-catch case 
    // Necessary to check whether myexcept is derived 
    // from exception 
    try 
    { 
     throw myexcept(); 
    } 
    catch(exception const & e) 
    {} 

    // 3. Nested function call 
    // Recursion necessary 
    bar(); 
} 

Mit Vorlagen in C++ für jede Art instanziiert wird, sowieso Anwendungen dauert ewig Kompilieren - warum also nicht noexcept ändern, den Compiler zu zwingen, zu prüfen, ob Ausnahmen geworfen werden während Zeit kompilieren?

Die einzige Schwierigkeit, die ich sehe, ist, dass eine Funktion je nach Laufzeitzuständen werfen kann oder nicht - aber diese Funktion sollte sich meiner Meinung nach noexcept sowieso nicht nennen dürfen.

Fehle ich etwas oder war es die Absicht, die Kompilierungszeit nicht weiter zu erhöhen, oder die Compiler-Entwickler zu beschneiden?

+13

Es gibt keine Möglichkeit für den Compiler zu wissen, ob beispielsweise eine Bibliotheksfunktion, die Sie innerhalb Ihrer Funktion aufrufen, eine Ausnahme auslöst. – lapk

+4

'throw()' ist eine Garantie für den Compiler. 'noexcept' ist eine Garantie für den Compiler. –

+0

@PetrBudnik: Natürlich gibt es jede Funktion, die nicht als "noexcept" markiert ist. –

Antwort

1

Ich denke, dass vieles davon auf die Tatsache zurückzuführen ist, dass Compilerschreiber, wenn Exception-Spezifikationen definiert wurden, weit hinter der Leistungskurve lagen. Implementieren von C++ 98 als ausreichend komplex, dass es nur einen Compiler gibt, der sogar beansprucht, um alle seine Funktionen zu implementieren. Jeder andere Compiler hat mindestens ein Hauptmerkmal ausgelassen, das im Standard enthalten war. Die meisten haben ganz offen zugegeben, dass sie wesentlich mehr ausgelassen haben.

Sie müssen auch bedenken, dass dynamische Ausnahmespezifikationen auch wesentlich komplexer waren als nur throw(). Es ermöglicht einem Programmierer, eine willkürliche Menge von Typen anzugeben, die geworfen werden können. Schlimmer noch, die Angabe, dass eine Funktion foo auslösen kann, bedeutet, dass sie auch alles ableiten kann, das von foo abgeleitet wurde.

Statische Ausnahmeregelungen könnten zwar durchgeführt worden sein, aber es hätte eindeutig eine Menge zusätzlicher Arbeit hinzugefügt, und niemand war sich wirklich sicher, welchen Nutzen es hätte (falls überhaupt). Unter den gegebenen Umständen war es für die meisten ziemlich einfach zu denken, dass die statische Durchsetzung etwas ist, das später benötigt werden könnte, wenn es ausreichend genutzt würde, um die Arbeit zu rechtfertigen. Wenn Sie von der Erzwingung zur Laufzeit zur Kompilierungszeit wechseln, müssen Sie keinen vorhandenen Code ändern, sondern nur vorhandene Implementierungen.

Ein weiterer Punkt ist, dass ich bin mir nicht sicher, dass es jemals wirklich starke Unterstützung von Ausnahmen Spezifikationen sowieso. Ich denke, es gab allgemeine Übereinstimmung über die Grundidee, aber wenn Sie sich damit beschäftigen, wahrscheinlich weniger über die Details.

Fazit: Es war einfach, nur dynamische Durchsetzung zu beauftragen, und statische Durchsetzung für später (wenn überhaupt) zu lassen. Es stellte sich heraus, dass die statische Durchsetzung in der Regel nicht wirklich viel Positives hinzufügen würde, also hätte es wahrscheinlich nicht viel bewirkt.

Verwandte Themen