Ausnahmebehandlung

Im Computer und Computerprogrammierung, Ausnahmebehandlung ist der Prozess der Reaktion auf das Auftreten von Ausnahmen - Anomale oder außergewöhnliche Bedingungen, die eine besondere Verarbeitung erfordern - während der Hinrichtung von a Programm. Im Allgemeinen bricht eine Ausnahme den normalen Ausführungsfluss und führt einen vorregistrierten Durchgang aus Ausnahmebehandler; Die Details darüber, wie dies getan wird, hängt davon ab, ob es a ist Hardware- oder Software Ausnahme und wie die Software -Ausnahme implementiert wird. Ausnahmebehandlung, falls vorhanden, wird durch Spezialisierung erleichtert Programmiersprache Konstrukte, Hardwaremechanismen wie Interrupts, oder Betriebssystem (Betriebssystem) Interprozesskommunikation (IPC) Einrichtungen wie Signale. Einige Ausnahmen, insbesondere Hardware, können so anmutig behandelt werden, dass die Ausführung dort wieder aufnehmen kann, wo sie unterbrochen wurde.

Definition

Die Definition einer Ausnahme basiert auf der Beobachtung, dass jeweils jeder Verfahren hat ein Voraussetzung, eine Reihe von Umständen, für die es "normal" beendet.[1] Ein Ausnahmebehandlungsmechanismus ermöglicht das Verfahren Erhöhen Sie eine Ausnahme[2] Wenn diese Voraussetzung verletzt wird,[1] Zum Beispiel, wenn das Verfahren auf eine abnormale Argumente aufgerufen wurde. Der Ausnahmebehandlungsmechanismus dann Griffe die Ausnahme.[3] Die Voraussetzung und die Definition von Ausnahme ist, ist subjektiv. Die Menge der "normalen" Umstände wird vollständig vom Programmierer definiert, z. Der Programmierer kann die Division für Null als undefiniert halten, daher eine Ausnahme oder ein Verhalten wie die Rückgabe von Null oder einen speziellen "Null -Dividen -Wert" (Umgehung der Notwendigkeit von Ausnahmen).[4] Gemeinsame Ausnahmen umfassen ein ungültiges Argument (z. B. Wert liegt außerhalb der Domäne einer Funktion), eine nicht verfügbare Ressource (wie eine fehlende Datei, ein Festplattenfehler oder außerhalb des Memory-Fehlers) oder dass die Routine eine normale Bedingung erkannt hat, die eine spezielle Handhabung erfordert, z. B. Aufmerksamkeit, das Ende der Datei.

Ausnahmebehandlung löst die Semipredicate -ProblemDort unterscheidet der Mechanismus normale Rückgaberwerte von fehlerhaften. In Sprachen ohne integrierte Ausnahmebehandlung wie C müssten Routinen den Fehler auf andere Weise signalisieren, wie z. B. das gemeinsame Rückgabe Code und Errno Muster.[5] Wenn Sie eine breite Sichtweise betrachten, können Fehler als eine ordnungsgemäße Teilmenge von Ausnahmen angesehen werden.[6] und explizite Fehlermechanismen wie ERRNO können (ausführliche) Formulare der Ausnahmebehandlung betrachtet werden.[5] Der Begriff "Ausnahme" wird dem "Fehler" bevorzugt, da er nicht bedeutet, dass etwas falsch ist - eine Bedingung, die von einem Verfahren oder einem Programmierer als Fehler angesehen wird, wird möglicherweise nicht so von einem anderen. Sogar der Begriff "Ausnahme" kann irreführend sein, da seine typische Konnotation von "Ausreißer" darauf hinweist, dass etwas seltenes oder Ungewöhnliches aufgetreten ist, wenn tatsächlich die Ausnahme eine normale und übliche Situation im Programm sein kann.[7] Nehmen wir zum Beispiel eine Suchfunktion für eine an, für eine Assoziatives Array Wirft eine Ausnahme aus, wenn der Schlüssel keinen Wert zugeordnet hat. Abhängig vom Kontext kann diese Ausnahme von "Schlüssel abwesend" viel häufiger auftreten als eine erfolgreiche Suche.[8]

Ein wesentlicher Einfluss auf den Umfang und die Verwendung von Ausnahmen ist der soziale Druck, d. H. "Beispiele für die Verwendung, die normalerweise in Kernbibliotheken zu finden ist, und Code -Beispiele in technischen Büchern, Magazinartikeln und Online -Diskussionsforen sowie in den Code -Standards einer Organisation".[9]

Geschichte

Die erste Handhabung der Hardware -Ausnahme wurde in der gefunden Univac i Ab 1951 führte der arithmetische Überlauf zwei Anweisungen unter der Adresse 0 aus, die die Kontrolle übertragen oder das Ergebnis festlegen konnten.[10]

In den 1960er und 1970er Jahren wurde die Handhabung der Software -Ausnahme entwickelt. Lisp 1.5 (1958-1961)[11] erlaubte Ausnahmen, die von der erhoben werden sollen ERROR Pseudofunktion, ähnlich wie beim Dolmetscher oder Compiler Fehler. Ausnahmen wurden von der gefangen Fehler Schlüsselwort, das zurückgegeben wurde NULL Bei einem Fehler, anstatt das Programm zu beenden oder den Debugger einzugeben.[12] Pl/i stellte um 1964 eine eigene Form der Ausnahmebehandlung vor, sodass Interrupts mit Einheiten behandelt werden können.[13] MacLisp beobachtete das Irrieren und IRREN wurden nicht nur für die Erhöhung des Fehlers, sondern auch für den nicht lokalen Kontrollfluss verwendet und somit zwei neue Schlüsselwörter hinzugefügt. FANG und WURF (Juni 1972).[14] Das Aufräumverhalten, das jetzt allgemein "endlich" bezeichnet wurde NULL (Neue Implementierung von Lisp) Mitte bis Ende der 1970er Jahre als Entspannungsschutz.[15] Dies wurde dann von übernommen von Common Lisp. Zeitgenössisch damit war Dynamikwind im Schema, das Ausnahmen von Schließungen abwickelte. Die ersten Papiere zum strukturierten Ausnahmehandling waren Goodenough (1975a) und Goodenough (1975b).[16] Anschließend wurde von vielen Programmiersprachen ab den 1980er Jahren weit verbreitet.

Hardwareausnahmen

Es gibt keinen klaren Konsens über die genaue Bedeutung einer Ausnahme in Bezug auf Hardware.[17] Aus Sicht der Implementierung wird es identisch mit einem gehandhabt unterbrechen: Der Prozessor hält die Ausführung des aktuellen Programms an, schaut die nach Interrupt Handler in dem Vektortabelle unterbrechen Für diese Ausnahme oder Interrupt -Bedingung speichert der Zustand und schaltet die Steuerung.

IEEE 754 Floating-Punkt-Ausnahmen

Ausnahmebehandlung in der IEEE 754 Schwimmpunkt Standard bezieht sich im Allgemeinen auf außergewöhnliche Bedingungen und definiert eine Ausnahme als "ein Ereignis, das auftritt, wenn ein Betrieb in bestimmten Operanden für jede vernünftige Anwendung kein Ergebnis hat. Diese Operation kann eine oder mehrere Ausnahmen signalisieren , eine sprachdefinierte alternative Handhabung. "

Standardmäßig ist eine IEEE 754 -Ausnahme wiederbelebt und wird durch Ersetzen eines vordefinierten Werts für verschiedene Ausnahmen, z. Unendlichkeit für eine Kluft durch Null -Ausnahme und Bereitstellung von Statusflags für die spätere Überprüfung, ob die Ausnahme aufgetreten ist (siehe C99 Programmiersprache für ein typisches Beispiel für die Handhabung von IEEE 754 Ausnahmen). Ein durch die Verwendung von Statusflags ermöglichtes Ausnahmebehandlungsstil beinhaltet: ZUSAMMENFASSUNG EINEN Ausdruck mit einer schnellen, direkten Implementierung; Überprüfen Sie, ob es fehlschlägt, indem Statusflags getestet werden; und dann, falls erforderlich, rufen Sie einen langsameren, numerisch robusteren Implementierung an.[18]

Der IEEE 754-Standard verwendet den Begriff "Fangen", um sich auf die Aufruf einer von Benutzer gelieferten Ausnahmebehandlung unter außergewöhnlichen Bedingungen zu beziehen, und ist eine optionale Funktion des Standards. Der Standard empfiehlt hierfür mehrere Verwendungsszenarien, einschließlich der Implementierung der nicht defekten Vorsachen eines Werts, gefolgt von einer Wiederaufnahme, um präzise zu handhaben Abnehmbare Singularitäten.[18][19][20]

Das Standardverhalten der IEEE 754-Ausnahmebehandlung der Wiederaufnahme nach der Vorsutschierung eines Standardwerts vermeidet die Risiken, die beim Ändern der Programmregelung der Programmsteuerung auf numerische Ausnahmen verbunden sind. Zum Beispiel das 1996 Cluster -Raumschiff Der Start endete mit einer katastrophalen Explosion, die teilweise auf die Ada Ausnahmebehandlungspolitik der Abbreitung der Berechnung zum arithmetischen Fehler. William Kahan behauptet, dass das Standardverhalten von IEEE 754 Ausnahmeberechnung dies verhindert hätte.[19]

Ausnahmeunterstützung in Programmiersprachen

Die Handhabung der Software -Ausnahme und die Unterstützung von Software -Tools unterscheidet sich etwas von dem, was durch Ausnahmehandhabung in Hardware verstanden wird, aber ähnliche Konzepte sind beteiligt. In der Programmiersprachmechanismen für Ausnahmebehandlung der Begriff Ausnahme wird typischerweise in einem bestimmten Sinne verwendet, um eine Datenstruktur zu bezeichnen, die Informationen zu einer außergewöhnlichen Bedingung speichert. Ein Mechanismus zur Übertragung der Kontrolle oder heben Eine Ausnahme ist bekannt als a Wurf. Die Ausnahme soll sein geworfen. Die Ausführung wird auf einen "Fang" übertragen.

Programmiersprachen unterscheiden sich erheblich in ihrer Vorstellung davon, was eine Ausnahme ist. Zeitgenössische Sprachen können ungefähr in zwei Gruppen unterteilt werden:[9]

  • Sprachen, bei denen Ausnahmen als Durchflussregelungsstrukturen ausgelegt sind: ADA, Modula-3, ML, Ocaml, PL/I, Python und Ruby fallen in diese Kategorie. Zum Beispiel, Pythons Iteratoren Ausnahmen der Stoppitationation auf die Signalwende, dass der Iterator keine weiteren Elemente erzeugt wird.[21]
  • Sprachen, in denen Ausnahmen nur zum Umgang mit abnormalen, unvorhersehbaren, fehlerhaften Situationen verwendet werden: C ++,,[22] Java,[23] C#, Common Lisp, Eiffel und Modula-2.

PL/Ich verwendete dynamisch Scoped -Ausnahmen. Die PL/I-Ausnahmehandhabung enthielt Ereignisse, die keine Fehler sind, z. B. Aufmerksamkeit, Dateiende, Änderung der aufgelisteten Variablen.

Syntax

Viele Computersprachen haben eine integrierte syntaktische Unterstützung für Ausnahmen und Ausnahmebehandlung. Das beinhaltet Aktionen, Ada, Blitzmax, C ++, C#, Clojure, Cobol, D, ECMaskript, Eiffel, Java, Ml, Objekt Pascal (z.B. Delphi, Kostenloser Pascalund dergleichen), Powerbuilder, Ziel c, Ocaml, Php (Ab Version 5),, Pl/i, PL/sql, Prolog, Python, Realbasic, Rubin, Scala, Samen7, Smalltalk, Tcl, Visueller Prolog Und die meisten .NETZ Sprachen.

Ohne kleinere syntaktische Unterschiede werden nur wenige Ausnahmebehörigstile verwendet. Im beliebtesten Stil wird eine Ausnahme durch ein Sonderangebot initiiert (Wurf oder heben) mit einem Ausnahmeobjekt (z. B. mit Java oder Objektpascal) oder einem Wert eines speziellen erweiterbaren, aufzähligen Typs (z. B. mit ADA oder SML). Der Umfang für Ausnahmebehandler beginnt mit einer Markerklausel (Versuchen oder der Blockstarter der Sprache wie z. Start) und endet zu Beginn der ersten Handlerklausel (Fang, außer, Rettung). Es können mehrere Handler -Klauseln folgen, und jeder kann angeben, welche Ausnahmetypen sie behandeln und welchen Namen sie für das Ausnahmeobjekt verwendet. Als geringfügige Variation verwenden einige Sprachen eine einzelne Handlerklausel, die sich mit der Klasse der Ausnahme intern befasst.

Ebenfalls häufig ist eine verwandte Klausel (endlich oder dafür sorgen) Das wird ausgeführt, ob eine Ausnahme aufgetreten ist oder nicht, normalerweise um die im Körper des Ausnahmebehälters erworbenen Ressourcen freizusetzen. Insbesondere liefert C ++ dieses Konstrukt nicht und empfiehlt stattdessen die Ressourcenerwerb ist die Initialisierung (RAII) -Technik, die Ressourcen nutzen Zerstörer.[24] Laut einer Arbeit von Westley Weimer und einer Zeitung von 2008 George Neculadie Syntax der Versuchen...endlich Blöcke in Java sind ein Faktor für Softwarefehler. Wenn eine Methode die Akquisition und Freigabe von 3 bis 5 Ressourcen abwickeln muss, sind Programmierer aufgrund der Lesbarkeitsbedenken offenbar nicht bereit, genügend Blöcke zu nisten, selbst wenn dies eine korrekte Lösung wäre. Es ist möglich, eine einzelne zu verwenden Versuchen...endlich Blockieren Sie auch beim Umgang mit mehreren Ressourcen, aber das erfordert eine korrekte Verwendung von Sentinel -Werte, was eine weitere häufige Fehlerquelle für diese Art von Problem ist.[25]: 8: 6–8: 7

Python und Ruby erlauben auch eine Klausel (anders) Das wird verwendet, wenn keine Ausnahme vor dem Ende des Umfangs des Handlers erreicht wurde.

In seiner Ganze könnte der Ausnahmebehandlungscode so aussehen (in Java-wie Pseudocode):

Versuchen {  Linie = Konsole.Zeile lesen();  wenn (Linie.Länge() == 0) {  Wurf Neu LeereLeexception("Die von der Konsole gelesene Zeile war leer!");  }  Konsole.Drucklinie("Hallo %s!" % Linie); } Fang (LeereLeexception e) {  Konsole.Drucklinie("Hallo!"); } Fang (Ausnahme e) {  Konsole.Drucklinie("Fehler: " + e.Botschaft()); } anders {  Konsole.Drucklinie("Das Programm lief erfolgreich."); } endlich {  Konsole.Drucklinie("Das Programm endet jetzt."); } 

C hat keine Versuchs-Ausnahmebehandlung, sondern verwendet, verwendet aber Rückgabecodes zur Fehlerprüfung. Das setjmp und longjmp Standardbibliotheksfunktionen können verwendet werden, um die Versuchs-Catch-Handhabung über Makros zu implementieren.[26]

Perl 5 Verwendungen sterben zum Wurf und eval {} if ($@) {} Für Versuch. Es verfügt über CPAN-Module, die Try-Catch-Semantik bieten.[27]

Beendigung und Wiederaufnahmesemantik

Wenn eine Ausnahme ausgelöst wird, sucht das Programm durch die zurück Stapel von Funktionsaufrufen, bis ein Ausnahmebehandler gefunden wurde. Einige Sprachen fordern abwickeln Der Stapel im Laufe dieser Suche. Das heißt, wenn auch Funktion f, mit einem Handler H für Ausnahme E, Anruffunktion g, was wiederum die Funktion nennt hund eine Ausnahme E tritt auf in hdann funktioniert h und g kann beendet werden und H in f wird umgehen E. Dies soll eine Kündigungssemantik sein. Alternativ können die Ausnahmebehandlungsmechanismen den Stapel nicht abwickeln, was dem Ausnahmebehandler die Möglichkeit gibt, die Berechnung, den Lebenslauf oder die Entspannung neu zu starten. Auf diese Weise kann das Programm die Berechnung genau an derselben Stelle fortsetzen, an der der Fehler aufgetreten ist (z. B. wenn eine zuvor fehlende Datei verfügbar geworden ist) oder Benachrichtigungen, Protokollierung, Abfragen und Flüssigkeitsvariablen oben auf dem Ausnahmebehandlungsmechanismus (wie erlegt in SmallTalk). Wenn die Berechnung wieder aufgenommen wird, wo sie aufgelassen wird, wird die Wiederaufnahmesemantik bezeichnet.

Es gibt theoretische und Designargumente für jede Entscheidung. C ++ Standardisierungsdiskussionen in den Jahren 1989–1991 führten zu einer endgültigen Entscheidung, die Beendigungssemantik in C ++ zu verwenden.[28] Bjarne Stroustrup zitiert eine Präsentation von Jim Mitchell Als Schlüsseldatenpunkt:

Jim hatte über einen Zeitraum von 20 Jahren Ausnahmebehandlung in einem halben Dutzend Sprachen verwendet und war ein früher Befürworter der Wiederaufnahmesemantik als einer der Hauptdesigner und Implementierer von Xerox's Cedar/Mesa System. Seine Botschaft war

„Die Beendigung wird gegenüber der Wiederaufnahme bevorzugt. Dies ist keine Meinung, sondern eine Frage der jahrelangen Erfahrung. Wiederaufnahme ist verführerisch, aber nicht gültig. “

Er unterstützte diese Aussage mit Erfahrung aus mehreren Betriebssystemen. Das zentrale Beispiel war Cedar/Mesa: Es wurde von Personen geschrieben, die eine Wiederaufnahme verwendeten, aber nach zehn Jahren der Verwendung gab es nur noch eine Wiederaufnahme im halben Million Zeilensystem - und das war eine Kontextanfrage. Da die Wiederaufnahme für eine solche Kontextanfrage nicht notwendig war, haben sie sie entfernt und eine erhebliche Geschwindigkeitssteigerung in diesem Teil des Systems festgestellt. In jedem Fall, in dem die Wiederaufnahme verwendet worden war, wurde sie - über die zehn Jahre - zu einem Problem geworden, und ein angemesseneres Design hatte es ersetzt. Grundsätzlich hatte jede Wiederaufnahme der Wiederaufnahme das Versäumnis dargestellt, getrennte Abstraktionsniveaus disjunkt zu führen.[16]

Ausnahmebehandlung mit Wiederaufnahmen umfassen Common Lisp mit Bedingungensystem, Pl/i, dylan und Smalltalk. Die Mehrheit der neueren Programmiersprachen folgt jedoch C ++ und verwendet die Beendigungssemantik.

Implementierung der Ausnahmehandhabung

Die Implementierung der Ausnahmebehandlung in Programmiersprachen beinhaltet in der Regel sowohl von einem Codegenerator als auch von der Laufzeitsystem Begleiten Sie einen Compiler. (Es war die Hinzufügung einer Ausnahmehandhabung zu C ++, die die nützliche Lebensdauer des ursprünglichen C ++ - Compilers beendete. CFRONT.[29]) Zwei Schemata sind am häufigsten. Der Erste, Dynamische Registrierunggeneriert Code, der Strukturen über den Programmstatus in Bezug auf die Ausnahmebehandlung kontinuierlich aktualisiert.[30] In der Regel fügt dies dem ein neues Element hinzu Stapelrahmenlayout Das weiß, welche Handler für die Funktion oder Methode zur Verfügung stehen. Wenn eine Ausnahme ausgelöst wird, leitet ein Zeiger im Layout die Laufzeit auf den entsprechenden Handlercode. Dieser Ansatz ist in Bezug auf den Raum kompakt, fügt jedoch den Ausführungsaufwand beim Rahmeneintrag und beim Ausgang hinzu. Es wurde häufig in vielen ADA -Implementierungen verwendet, beispielsweise bei vielen anderen Sprachmerkmalen, bei denen eine komplexe Generation und Laufzeitunterstützung erforderlich war. Microsoft 32-Bit Strukturierte Ausnahmebehandlung (SEH) verwendet diesen Ansatz mit einem separaten Ausnahmestapel.[31] Die dynamische Registrierung, die ziemlich einfach zu definieren ist, ist zugänglich für Nachweis der Korrektheit.[32]

Das zweite Schema und das in vielen Produktionsqualität C ++-Compilern und 64-Bit-Microsoft implementiert Seh, ist ein tabelletrieben sich nähern. Dies schafft statische Tabellen bei Zeit kompilieren und Linkzeit das bezieht Bereiche der Programm zähler in den Programmzustand in Bezug auf Ausnahmebehandlung.[33] Wenn dann eine Ausnahme ausgelöst wird, schaut das Laufzeitsystem den aktuellen Anweisungsort in den Tabellen nach und bestimmt, was Handler im Spiel sind und was getan werden muss. Dieser Ansatz minimiert Executive Overhead für den Fall, in dem eine Ausnahme nicht ausgelöst wird. Dies geschieht auf Kosten eines Raums, aber dieser Raum kann in schreibgeschützte, spezielle Datenabschnitte zugeordnet werden, die erst dann geladen oder verschoben werden, wenn eine Ausnahme tatsächlich ausgelöst wird.[34] Der Standort (im Speicher) des Codes für den Umgang mit einer Ausnahme muss nicht innerhalb (oder sogar in der Nähe) im Speicherbereich gefunden werden, in dem der Rest des Funktionscodes gespeichert ist. Wenn also eine Ausnahme ausgelöst wird, ist ein Performance -Treffer - ungefähr vergleichbar mit einem Funktionsaufruf[35] - kann auftreten, wenn der erforderliche Ausnahmecode geladen/zwischengespeichert werden muss. Dieses Schema hat jedoch minimale Leistungskosten, wenn keine Ausnahme ausgelöst wird. Da Ausnahmen in C ++ sein sollen außergewöhnlich (d.h. ungewöhnliche/seltene) Ereignisse der Phrase "Null-Kosten-Ausnahmen"[Anmerkung 1] wird manchmal verwendet, um die Ausnahmebehandlung in C ++ zu beschreiben. Wie Identifizierung von Laufzeittyp (RTTI), Ausnahmen halten sich möglicherweise nicht an C ++, Zero-Overhead-Prinzip Als Implementierung der Ausnahmebehandlung zur Laufzeit erfordert eine Menge Speicher für die Nachschlagtabelle.[36] Aus diesem Grund können die Ausnahmebehandlung (und RTTI) in vielen C ++ - Compilern deaktiviert werden, was für Systeme mit sehr begrenztem Speicher nützlich sein kann[36] (wie zum Beispiel eingebettete Systeme). Dieser zweite Ansatz ist auch in Bezug auf das Erreichen überlegen Fadensicherheit.

Andere Definitions- und Implementierungssysteme wurden ebenfalls vorgeschlagen. Für Sprachen, die unterstützen Metaprogrammierung, Ansätze, die überhaupt keinen Overhead beinhalten (jenseits der bereits gegenwärtigen Unterstützung für Betrachtung) wurden fortgeschritten.[37]

Ausnahmebehandlung basierend auf dem Entwurf durch Vertrag

Eine andere Sichtweise der Ausnahmen basiert auf den Prinzipien von Entwurf durch Vertrag und wird insbesondere durch die unterstützt Eiffeltelsprache. Die Idee ist, eine strengere Grundlage für die Ausnahmebehandlung zu bieten, indem genau das "normale" und "abnormale" Verhalten definiert wird. Insbesondere basiert der Ansatz auf zwei Konzepten:

  • Versagen: Die Unfähigkeit einer Operation, seinen Vertrag zu erfüllen. Beispielsweise kann ein Addition einen arithmetischen Überlauf erzeugen (er erfüllt seinen Vertrag, eine gute Annäherung an die mathematische Summe zu berechnen). oder eine Routine kann ihre Postkondition nicht erfüllen.
  • Ausnahme: Ein abnormales Ereignis, das während der Ausführung einer Routine auftritt (diese Routine ist das "Empfänger"von der Ausnahme) während ihrer Ausführung. Ein solches abnormales Ereignis ergibt sich aus dem Versagen einer von der Routine genannten Operation.

Das "sichere Ausnahme -Handling -Prinzip", wie von Bertrand Meyer in eingeführt Objektorientierte Softwarekonstruktion Dann ist es der Ansicht, dass es nur zwei sinnvolle Möglichkeiten gibt, wie eine Routine reagieren kann, wenn eine Ausnahme eintritt:

  • Versagen oder "organisierte Panik": Die Routine behebt den Zustand des Objekts, indem die Invariante wieder hergestellt wird (dies ist der "organisierte" Teil) und dann fehlschlägt (Panik), was eine Ausnahme in seinem Anrufer auslöst (so dass das abnormale Ereignis ist nicht ignoriert).
  • Wiederholung: Die Routine versucht den Algorithmus erneut, normalerweise nach dem Ändern einiger Werte, so dass der nächste Versuch eine bessere Chance hat, erfolgreich zu sein.

Insbesondere ist es nicht zulässig, eine Ausnahme einfach zu ignorieren. Ein Block muss entweder wiedergegeben und erfolgreich abgeschlossen werden oder die Ausnahme an seinen Anrufer ausbreiten.

Hier ist ein Beispiel in der Eiffeltax. Es wird angenommen, dass eine Routine send_fast ist normalerweise der bessere Weg, eine Nachricht zu senden, aber sie kann fehlschlagen und eine Ausnahme auslöst. Wenn ja, verwendet der Algorithmus als nächstes send_slow, was seltener scheitert. Wenn send_slow scheitert die Routine send Insgesamt sollte der Anrufer scheitern, was eine Ausnahme erhält.

senden (m: BOTSCHAFT) ist  - Senden Sie M durch schnelle Link, wenn möglich, sonst durch langsames Link. lokal  Probig, stut_slow: Boolesche tun  wenn Probig dann  stut_slow : = WAHR  send_slow (m)  anders  Probig : = WAHR  schnell senden (m)  Ende Rettung  wenn nicht stut_slow dann  wiederholen  Ende Ende 

Die lokalen variablen booleschen Variablen werden zu Beginn auf False initialisiert. Wenn send_fast versagt, der Körper (do Klausel) wird erneut ausgeführt, was die Ausführung von verursacht send_slow. Wenn diese Ausführung von send_slow scheitert, die rescue Klausel wird bis zum Ende mit nein ausgeführt retry (nein else Klausel im Finale if), was dazu führt, dass die Routineausführung als Ganzes scheitert.

Dieser Ansatz hat den Verdienst, klar zu definieren, was "normale" und "abnormale" Fälle sind: ein abnormaler Fall, der eine Ausnahme verursacht, ist eine, in der die Routine ihren Vertrag nicht erfüllen kann. Es definiert eine klare Verteilung der Rollen: die do Klausel (Normalgremium) ist für den Vertrag der Routine verantwortlich oder versucht zu erreichen. das rescue Die Klausel ist für die Wiederherstellung des Kontextes und den Neustart des Prozesses zuständig, wenn dies die Chance hat, erfolgreich zu sein, aber keine tatsächliche Berechnung durchzuführen.

Obwohl Ausnahmen in Eiffel eine ziemlich klare Philosophie haben, kritisiert Kiniry (2006) ihre Implementierung, weil "Ausnahmen, die Teil der Sprachdefinition sind sind Grundwerte und keine Objekte, sie haben keine inhärente Semantik, die über das hinausgeht, was in einer Helferroutine ausgedrückt wird, die aufgrund der Überlastung der Darstellung notwendigerweise nicht narrensicher sein kann (z. B. kann man zwei Ganzzahlen nicht unterscheiden). "[9]

Unzereinte Ausnahmen

Zeitgenössische Anwendungen stehen vor vielen Designherausforderungen, wenn sie Ausnahmebehandlungstrategien in Betracht ziehen. Insbesondere in modernen Anwendungen auf Unternehmensebene müssen Ausnahmen häufig Prozessgrenzen und Maschinengrenzen überschreiten. Ein Teil der Gestaltung einer soliden Ausnahmeregelungstrategie ist das Erkenntnis, wann ein Prozess nicht so fehlgeschlagen ist, dass der Software -Teil des Prozesses wirtschaftlich nicht wirtschaftlich behandelt werden kann.[38]

Wenn eine Ausnahme ausgelöst und nicht erwischt wird (operativ, wird eine Ausnahme ausgelöst, wenn kein anwendbarer Handler angegeben ist), wird die unkausleitende Ausnahme von der Laufzeit behandelt. Die Routine, die dies tut, heißt die Unbefundter Ausnahmebehandler.[39][40] Das häufigste Standardverhalten besteht darin, das Programm zu beenden und eine Fehlermeldung an die Konsole zu drucken. In der Regel enthält Debug -Informationen wie eine String -Darstellung der Ausnahme und die Stapelspur.[39][41][42] Dies wird oft durch einen Handler auf höchster Ebene (Anwendungsebene) vermieden (zum Beispiel in einem Ereignisschleife) Das fängt Ausnahmen vor, bevor sie die Laufzeit erreichen.[39][43]

Beachten Programm Beenden Sie abnormal (das Programm ist möglicherweise nicht korrekt, wenn eine Ausnahme nicht erfasst wird, insbesondere wenn sie nicht teilweise abgeschlossene Transaktionen zurückrollen oder Ressourcen nicht freigeben), die Prozess endet normalerweise (unter der Annahme, dass die Laufzeit korrekt funktioniert), da die Laufzeit (die die Ausführung des Programms kontrolliert) sicherstellen kann, dass die ordnungsgemäße Abschaltung des Prozesses.

In einem Multithread-Programm kann eine ungewöhnliche Ausnahme in einem Thread stattdessen zu einer Beendigung dieses Threads führen, nicht zu dem gesamten Prozess (unbefestigte Ausnahmen im Handler auf Thread-Ebene werden vom Handler der oberen Ebene gefangen). Dies ist besonders wichtig für Server, wo zum Beispiel a Servlet (In seinem eigenen Thread) kann beendet werden, ohne dass der Server insgesamt betroffen ist.

Dieser nicht globale Ausnahmebehandler ausnahmslos oder pro-Thread kann beispielsweise entweder global oder pro Thread überschrieben werden, um alternative Protokollierung oder Endbenutzer berichten zu können, die unbekannte Ausnahmen berichten, oder um Threads neu zu starten, die aufgrund einer ungewöhnlichen Ausnahme enden. Zum Beispiel in Java wird dies für einen einzelnen Thread über durchgeführt Thread.setunaughexceptionHandler und global über Thread.SetDefaultUngaugtexceptionHandler; In Python erfolgt dies durch Modifikation sys.excepthook.

Überprüfte Ausnahmen

Java stellte den Begriff der überprüften Ausnahmen ein,[44][45] Welches sind besondere Klassen von Ausnahmen. Die überprüften Ausnahmen, die eine Methode erhöhen kann, muss Teil der Methode sein Unterschrift. Zum Beispiel, wenn eine Methode eine werfen könnte IOExceptionEs muss diese Tatsache in seiner Methodensignatur explizit erklären. Wenn Sie dies nicht tun, erhöht sich ein Kompilierungsfehler. Laut Hanspeter Mössenböck sind überprüfte Ausnahmen weniger bequem, aber robuster.[46] Überprüfte Ausnahmen können bei Zeit kompilieren, reduzieren die Inzidenz von nicht behandelten Ausnahmen auf Laufzeit in einer bestimmten Anwendung.

Kiniry schreibt, dass "wie jeder Java -Programmierer weiß, das Volumen von versuche fangen Der Code in einer typischen Java -Anwendung ist manchmal größer als der vergleichbare Code, der für explizite formale Parameter erforderlich ist, und die Rückgabewertprüfung in anderen Sprachen, die keine Ausnahmen überprüft haben. Tatsächlich ist der allgemeine Konsens zwischen Java-Programmierern in den Scheiben, dass der Umgang mit überprüften Ausnahmen fast genauso unangenehm ist wie die Schreibdokumentation. Daher berichten viele Programmierer, dass sie "ärgern", die Ausnahmen überprüft haben. "[9] Martin Fowler hat geschrieben "... im Großen und Ganzen denke ich, dass Ausnahmen gut sind, aber Java -überprüfte Ausnahmen sind mehr Ärger als sie wert sind."[47] Ab dem Jahr 2006 hat Java keine größere Programmiersprache beim Hinzufügen von geprüften Ausnahmen gefolgt.[47] Zum Beispiel, C# Erfordert oder erlaubt keine Erklärung von Ausnahmespezifikationen, wobei der folgende von Eric Gunnerson veröffentlicht wurde:[48][9][47]

"Die Untersuchung kleiner Programme führt zu der Schlussfolgerung, dass das Erfordernis der Ausnahmespezifikationen sowohl die Produktivität der Entwickler verbessern als auch die Codequalität verbessern kann. Die Erfahrung mit großen Softwareprojekten deuten jedoch auf ein anderes Ergebnis hin - verringerte Produktivität und wenig oder gar keine Zunahme der Codequalität."

Anders Hejlsberg beschreibt zwei Bedenken mit überprüften Ausnahmen:[49]

  • Versioning: Eine Methode kann deklariert werden, um Ausnahmen X und Y zu werfen. In einer späteren Version des Codes kann man Ausnahme Z aus der Methode nicht auswerfen, da der neue Code mit den früheren Verwendungen unvereinbar ist. Überprüfte Ausnahmen müssen die Anrufer der Methode entweder Z zu ihrer Throw -Klausel hinzufügen oder die Ausnahme verarbeiten. Alternativ kann Z als X oder ein Y falsch dargestellt werden.
  • Skalierbarkeit: In einem hierarchischen Design kann jedes System mehrere Subsysteme haben. Jedes Subsystem kann mehrere Ausnahmen machen. Jedes übergeordnete System muss sich mit den Ausnahmen aller darunter liegenden Subsysteme befassen, was zu einer exponentiellen Anzahl von Ausnahmen führt, die behandelt werden sollen. Überprüfte Ausnahmen erfordern, dass alle diese Ausnahmen explizit behandelt werden.

Um diese zu umgehen, sagt Hejlsberg, dass Programmierer die Funktion mit a umgehen können throws Exception Erklärung. Ein weiterer Umgang besteht darin, a zu verwenden try { ... } catch (Exception e) {} Handler.[49] Dies wird als Handhabung von Catch-All-Ausnahme bezeichnet oder Pokémon -Ausnahmehandling nach die Show"s Schlagwort" Ich muss sie alle fangen! ".[50] Die Java-Tutorials entmutigen die Aufnahme von Catch-All-Ausnahme, da es Ausnahmen erfassen kann, "für die der Hundeführer nicht beabsichtigt war".[51] Eine weitere entmutigte Umgehung besteht darin, alle Ausnahmen zu machen, die Unterklasse RuntimeException.[52] Eine ermutigte Lösung besteht darin, einen Catler-Handler oder eine Klausel zu verwenden, jedoch mit einem bestimmten Superklasse von allen potenziell geworfenen Ausnahmen und nicht der allgemeinen Superklasse Exception. Eine andere ermutigte Lösung besteht darin, Ausnahmestypen zu definieren und zu deklarieren, die für die Abstraktion der aufgerufenen Methode geeignet sind[53] und kartieren Ausnahmen mit niedrigerer Ebene von diesen Typen durch Verwendung Ausnahmeberächen.

Ähnliche Mechanismen

Die Wurzeln der überprüften Ausnahmen gehen zurück zum CLU -ProgrammierspracheBegriff der Ausnahmespezifikation.[54] Eine Funktion könnte nur Ausnahmen aufnehmen, die in ihrem Typ aufgeführt sind, aber alle aus undichte Ausnahmen von so genannten Funktionen würden automatisch in die alleinige Laufzeitausnahme umgewandelt. failure, anstatt zu Kompilierungs-Zeitfehler zu führen.[7] Später, Modula-3 hatte ein ähnliches Merkmal.[55] Diese Funktionen enthalten nicht die Kompilierungszeitprüfung, die im Konzept der überprüften Ausnahmen von zentraler Bedeutung ist.[54]

Frühe Versionen der C ++ - Programmiersprache enthielten einen optionalen Mechanismus, der den geprüften Ausnahmen ähnelt, genannt Ausnahmespezifikationen. Standardmäßig könnte jede Funktion jede Ausnahme auswerfen, dies könnte jedoch durch a begrenzt werden throw Klausel zur Funktionssignatur hinzugefügt, in der angegeben wurde, welche Ausnahmen die Funktion werfen kann. Die Ausnahmebetechnungen wurden zur Kompilierungszeit nicht durchgesetzt. Verstöße führten zur globalen Funktion std::unexpected gerufen werden.[56] Es könnte eine leere Ausnahmeregelung angegeben werden, die darauf hinwies, dass die Funktion keine Ausnahme ausführt. Dies wurde nicht standardmäßig gemacht, wenn die Ausnahmebehandlung in die Sprache hinzugefügt wurde eben.[56] Die explizite Verwendung leerer Ausnahmeberechnungen könnte es jedoch mit C ++ - Compilern ermöglichen, signifikante Optimierungen des Code- und Stapel -Layouts durchzuführen, die bei der Ausnahmebehandlung in einer Funktion ausgeschlossen sind.[34] Einige Analysten betrachteten die ordnungsgemäße Verwendung von Ausnahmespezifikationen in C ++ als schwer zu erreichen.[57] Diese Verwendung von Ausnahmespezifikationen wurde in enthalten C ++ 98 und C ++ 03, veraltet im 2012 C ++ - Sprachstandard (C ++ 11),[58] und wurde aus der Sprache in entfernt C ++ 17. Eine Funktion, die keine Ausnahmen auslöst noexcept Stichwort.

Ein ungekordener Ausnahmenanalysator existiert für die Ocaml Programmiersprache.[59] Das Tool meldet die Reihe von erhöhten Ausnahmen als erweiterte Signatur. Im Gegensatz zu geprüften Ausnahmen erfordert das Tool jedoch keine syntaktischen Anmerkungen und ist extern (d. H. Es ist möglich, ein Programm zu kompilieren und auszuführen, ohne die Ausnahmen zu überprüfen).

Dynamische Überprüfung von Ausnahmen

Der Punkt der Ausnahmebehandlungsroutinen besteht darin, sicherzustellen, dass der Code Fehlerbedingungen verarbeiten kann. Um festzustellen, dass die Routinen zur Ausnahme von Ausnahmen ausreichend robust sind, muss der Code mit einem breiten Spektrum ungültiger oder unerwarteter Eingänge vorgestellt werden, wie sie über Software erstellt werden können Fehlerinjektion und Mutationstests (Das wird manchmal auch als als bezeichnet Fuzz -Test). Eine der schwierigsten Arten von Software, für die Ausnahmebehandlungsroutinen geschrieben werden müssen, ist die Protokollsoftware, da eine robuste Protokollimplementierung vorbereitet sein muss, um Eingaben zu erhalten, die nicht den entsprechenden Spezifikationen (en) entsprechen.

Um sicherzustellen, dass eine aussagekräftige Regressionsanalyse während eines a Lebenszyklusprozess der SoftwareentwicklungJede Ausnahmeregelungsprüfung sollte stark automatisiert sein, und die Testfälle müssen auf wissenschaftliche, wiederholbare Weise generiert werden. Es gibt mehrere im Handel erhältliche Systeme, die solche Tests durchführen.

In Laufzeit -Motorumgebungen wie z. Java oder .NETZEs gibt Tools, die an die Laufzeit -Engine verbunden sind, und jedes Mal, wenn eine Ausnahme von Interesse eintritt, zeichnen sie Debugging -Informationen auf, die zum Zeitpunkt der Ausnahme im Speicher vorhanden waren (Rufen Sie Stack an und Haufen Werte). Diese Tools werden genannt Automatisierte Ausnahmebehandlung oder Fehler-Interception-Tools und Bereitstellung von Informationen für Ausnahmen.

Asynchrone Ausnahmen

Asynchrone Ausnahmen sind Ereignisse, die durch einen separaten Thread oder einen externen Prozess angesprochen werden, z. B. das Pressen Strg-c ein Programm zu unterbrechen und a zu erhalten Signaloder eine disruptive Nachricht wie "Stop" oder "Suspend" von einem anderen senden Ausführungsfaden.[60][61] Während synchrone Ausnahmen bei einem bestimmten auftreten Wurf Aussage, asynchrone Ausnahmen können jederzeit angehoben werden. Daraus folgt, dass der Compiler nicht optimiert werden kann, da das Fehlen asynchroner Ausnahmen nicht beweisen kann. Sie sind auch schwer korrekt zu programmieren, da asynchrone Ausnahmen während der Aufräumarbeiten blockiert werden müssen, um Ressourcenlecks zu vermeiden.

Programmiersprachen vermeiden oder begrenzen normalerweise die Handhabung der asynchronen Ausnahme, z. B. verbietet C ++, Ausnahmen von Signalhandlern zu erheben, und Java hat die Verwendung seiner ThreadDeath -Ausnahme veraltet, die verwendet wurde, damit ein Faden einen anderen stoppt.[62] Ein weiteres Merkmal ist ein semi-asynchroner Mechanismus, der eine asynchrone Ausnahme nur während bestimmter Programmvorgänge hervorruft. Zum Beispiel Java's Thread.interrupt() betrifft nur den Thread, wenn der Thread eine Operation aufruft, die wirft InterruptedException.[63] Das ähnliche Posix pthread_cancel API hat Rassenbedingungen, die es unmöglich machen, sicher zu verwenden.[64]

Bedingungensysteme

Common Lisp, Dylan und Smalltalk ein Bedingungensystem haben[65] (sehen Gemeinsames Lisp -Bedingungssystem) Das umfasst die oben genannten Ausnahmebehandlungssysteme. In diesen Sprachen oder Umgebungen das Aufkommen einer Erkrankung (eine "Verallgemeinerung eines Fehlers" nach Kent Pitman) impliziert einen Funktionsaufruf, und erst spät im Ausnahmebehandler kann die Entscheidung, den Stapel abzuwickeln, getroffen werden.

Bedingungen sind eine Verallgemeinerung von Ausnahmen. Wenn ein Zustand entsteht, wird ein angemessener Bedingungshandler in Stapelreihenfolge gesucht und ausgewählt, um den Zustand zu verarbeiten. Bedingungen, die keine Fehler darstellen, können sicher ganz unberechtigt bleiben; Ihr einziger Zweck kann darin bestehen, Hinweise oder Warnungen gegenüber dem Benutzer zu verbreiten.[66]

Kontinuierliche Ausnahmen

Dies hängt mit dem sogenannten zusammen Wiederaufnahmemodell von Ausnahmebehandlung, bei dem einige Ausnahmen bezeichnet werden sollen kontinuierlich: Es darf zu dem Ausdruck zurückkehren, der eine Ausnahme signalisierte, nachdem sie Korrekturmaßnahmen im Handler ergriffen haben. Das Bedingungensystem ist verallgemeinert: innerhalb des Handlers eines nicht schwerwiegenden Zustands (a.k.a. kontinuierliche Ausnahme) Es ist möglich, auf vordefinierte Neustartpunkte zu springen (a.k.a. Neustart) die zwischen dem Signalausdruck und dem Zustandshandler liegen. Neustart sind Funktionen, die über eine lexikalische Umgebung geschlossen sind, sodass der Programmierer diese Umgebung reparieren kann, bevor der Zustandshandler vollständig verließ oder den Stapel auch teilweise entspannt.

Ein Beispiel ist das Endseite Zustand in pl/i; Die Einheit kann für die nächste Seite Seiten -Anhängerzeilen und Header -Zeilen schreiben und dann durch die Ausführung des unterbrochenen Codes fällt.

Starten Sie den getrennten Mechanismus von der Politik neu

Das Umgang mit dem Zustand überdurchschnittlich liefert a Trennung des Mechanismus von der Politik. Neustarts bieten verschiedene mögliche Mechanismen zur Wiederherstellung von Fehler, wählen Sie jedoch nicht aus, welcher Mechanismus in einer bestimmten Situation angemessen ist. Das ist die Provinz des Bedingungsbehandlers, der (da sie sich in einem höheren Code befindet) Zugang zu einer breiteren Sichtweise hat.

Ein Beispiel: Angenommen, es gibt eine Bibliotheksfunktion, deren Ziel es ist, eine einzelne zu analysieren syslog Dateieingabe. Was sollte diese Funktion tun, wenn der Eintrag missgebildet ist? Es gibt keine richtige Antwort, da dieselbe Bibliothek für viele verschiedene Zwecke in Programmen eingesetzt werden kann. In einem interaktiven Protokoll-File-Browser könnte es das Richtige sein, den Eintrag ungerettet zurückzugeben, damit der Benutzer ihn sehen kann-aber in einem automatisierten Protokollsummizierprogramm kann das Richtige darin bestehen, Nullwerte für die zu liefern Unlesbare Felder, aber mit einem Fehler abbrechen, wenn zu viele Einträge missgebildet wurden.

Das heißt, die Frage kann nur in Bezug auf die breiteren Ziele des Programms beantwortet werden, die der allgemeinen Bibliotheksfunktion nicht bekannt sind. Dennoch ist das Beenden einer Fehlermeldung nur selten die richtige Antwort. Anstatt einfach mit einem Fehler zu verlassen, kann die Funktion möglicherweise RESTARTS festlegen Bieten Sie verschiedene Möglichkeiten, um fortzufahren - zum Beispiel, um den Protokolleintrag zu überspringen, Standard- oder Nullwerte für die unlesbaren Felder zu liefern, um den Benutzer nach den fehlenden Werten zu bitten. oder Um den Stapel und die Abbruchverarbeitung mit einer Fehlermeldung abzuwickeln. Die angebotenen Neustarts bilden die Mechanismen verfügbar für die Wiederherstellung von Fehler; Die Auswahl des Neustarts durch den Bedingungshandler liefert die Politik.

Kritik

Die Ausnahmebehandlung wird in der Software oft nicht korrekt behandelt, insbesondere wenn mehrere Ausnahmen ausgesetzt sind. Datenflussanalyse Von 5 Millionen Zeilen Java -Code wurden über 1300 Defekte der Ausnahmehandhabung festgestellt.[25] Weimer und Necula zitierten mehrere frühere Studien von anderen (1999–2004) und ihren eigenen Ergebnissen und schrieben, dass ein erhebliches Problem mit Ausnahmen darin besteht, dass sie "versteckte Kontroll-Flow-Pfade schaffen, die für Programmierer schwierig sind, über die Vernunft zu verhindern".[25]: 8:27 "Während Try-Catch-final konzeptionell einfach ist, hat es die komplizierteste Ausführungsbeschreibung in der Sprachspezifikation [Gosling et al. 1996] und erfordert vier verschachtelte" wenn "in seiner offiziellen englischen Beschreibung. Kurz gesagt, es enthält es eine große Anzahl an Eckfälle dass Programmierer oft übersehen. "[25]: 8: 13–8: 14

Ausnahmen als unstrukturierter Fluss erhöhen das Risiko von Ressourcenlecks (wie z. B. einem Abschnitt, der von a gesperrt ist Mutexoder eine vorübergehend eine Datei offen) oder einen inkonsistenten Zustand. Es gibt verschiedene Techniken für Resourcenmanagement in Gegenwart von Ausnahmen, die am häufigsten die kombiniert haben Muster entsorgen mit irgendeiner Form von Abwicklungsschutz (wie a endlich Klausel), die die Ressource automatisch freigibt, wenn die Steuerung einen Codeabschnitt verlässt.

Tony Hoare 1980 beschrieb die ADA -Programmiersprache Als "... eine Vielzahl von Merkmalen und Notationskonventionen sind viele von ihnen unnötig und einige von ihnen, z. Zuverlässigkeit ist kritisch [...]. Die nächste Rakete, die aufgrund eines Programmiersprachenfehlers in die Irre geraten ist . "[67]

Das gehen Entwickler glauben, dass die Versuchs-Catch-final idiomisch verschleiert Steuerfluss,[68] und stellte die außergewöhnliche Einführung ein panic/recover Mechanismus.[69] recover() unterscheidet sich von catch da kann es nur von innerhalb von a aufgerufen werden defer Codeblock in einer Funktion, sodass der Handler nur aufräumen und die Rückgabewerte der Funktion ändern und die Kontrolle nicht an einen willkürlichen Punkt innerhalb der Funktion zurückgeben kann.[70] Das defer Block selbst fungiert ähnlich wie a finally Klausel.

Ausnahmebehandlung in UI -Hierarchien

Front-End-Webrahmen, wie z. Reagieren und Vue, haben Fehlerbehandlungsmechanismen eingeführt, bei denen Fehler die UI -Komponentenhierarchie auf eine Weise ausbreiten, die analog zu den Fehlern ist, wie Fehler beim Ausführen von Code den Anrufstapel ausbreiten.[71][72] Hier dient der Fehlergrenzmechanismus als Analogon zum typischen Try-Catch-Mechanismus. Daher kann eine Komponente sicherstellen, dass Fehler aus ihren untergeordneten Komponenten gefangen und behandelt werden und sich nicht an übergeordnete Komponenten ausbreiten.

Zum Beispiel würde eine Komponente in Vue Fehler durch die Implementierung aufnehmen Fehler

Vue.Komponente('Elternteil', {  Schablone: '<div> <dlot> </slot> </div>',  Fehler: (irren, VM, die Info) => Alarm('Ein Fehler ist aufgetreten'); }) Vue.Komponente('Kind', {  Schablone: '<div> {{Cause_error ()}} </div>' ' }) 

Wenn Sie so in Markup verwendet werden:

<Elternteil>  <Kind> </Kind> Elternteil> 

Der von der untergeordnete Komponente erzeugte Fehler wird von der übergeordneten Komponente gefangen und behandelt.[73]

Siehe auch

Anmerkungen

  1. ^ Es gibt "Null [Verarbeitung] Kosten" nur, wenn keine Ausnahme ein Wurf ist (obwohl es Speicherkosten gibt, da Speicher für die Nachschlagetabelle benötigt wird). Es gibt einen (potenziell erheblichen) Kosten, wenn eine Ausnahme ausgelöst wird (dh wenn Wurf wird ausgeführt). Die Implementierung der Ausnahmebehandlung kann auch die möglichen Einschränkungen einschränken Compiler -Optimierungen das kann durchgeführt werden.

Verweise

  1. ^ a b Cristian, Flaviu (1980). "Ausnahmebehandlung und Software -Fehlertoleranz". Proc. 10. int. Symp. Auf Fehlertolerant Computing (FTCS-25 Nachdruck.) (6): 531–540. Citeseerx 10.1.1.116.8736. doi:10.1109/tc.1982.1676035. OCLC 1029229019. S2CID 18345469.
  2. ^ Goodenough 1975b, S. 683–684.
  3. ^ Goodenough 1975b, p. 684.
  4. ^ Schwarz 1982, S. 13–15.
  5. ^ a b Lang, jun; Stewart, David B. (März 1998). "Eine Studie über die Anwendbarkeit bestehender Ausnahmeregelungstechniken auf komponentenbasierte Echtzeit-Softwaretechnologie". ACM -Transaktionen zu Programmiersprachen und Systemen. 20 (2): 276. Citeseerx 10.1.1.33.3400. doi:10.1145/276393.276395. S2CID 18875882. Die vielleicht häufigste Form der von Software-Programmierern verwendeten Ausnahmebehandlungsmethode ist die „Rückkehrcode“ -Technik, die als Teil von C und Unix populär gemacht wurde.
  6. ^ Levin 1977, p. 5.
  7. ^ a b Liskov, B.H.; Snyder, A. (November 1979). "Ausnahmebehandlung in CLU" (PDF). IEEE -Transaktionen auf Software -Engineering. SE-5 (6): 546–558. doi:10.1109/tse.1979.230191. S2CID 15506879. Abgerufen 19. Dezember 2021.
  8. ^ Levin 1977, p. 4.
  9. ^ a b c d e Kiniry, J. R. (2006). "Ausnahmen in Java und Eiffel: Zwei Extreme in Ausnahmedesign und Anwendung". Fortgeschrittene Themen in Ausnahmebehandlungstechniken (PDF). Vorlesungsnotizen in Informatik. Vol. 4119. S. 288–300. doi:10.1007/11818502_16. ISBN 978-3-540-37443-5.
  10. ^ Smootherman, Mark. "Interrupts". Abgerufen 4. Januar 2022.
  11. ^ McCarthy, John (12. Februar 1979). "Geschichte von Lisp" ". www-formal.stanford.edu. Abgerufen 13. Januar 2022.
  12. ^ McCarthy, John; Levin, Michael I.; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P. (14. Juli 1961). LISP 1.5 -Programmierhandbuch (PDF). Abgerufen 13. Januar 2022.
  13. ^ "Die On -Erklärung" (PDF). IBM System/360 Betriebssystem, PL/I -Sprachspezifikationen (PDF). IBM. Juli 1966. p. 120. C28-6571-3.
  14. ^ Gabriel & Steele 2008, p. 3.
  15. ^ Weiß 1979, p. 194.
  16. ^ a b Stroustrup 1994, p. 392.
  17. ^ Hyde, Randall. "Kunst der Versammlung: Kapitel siebzehn". www.Plantationsproduktions.com. Abgerufen 22. Dezember 2021.
  18. ^ a b Xiaoye li; James Demmel (1994). "Schnellere numerische Algorithmen über Ausnahmebehandlung, IEEE -Transaktionen auf Computern, 43 (8)": 983–992. {{}}: Journal zitieren erfordert |journal= (Hilfe)
  19. ^ a b W.Kahan (5. Juli 2005). "Eine Demonstration der Vorsteuerung für ∞/∞" (PDF). Archiviert (PDF) Aus dem Original am 10. März 2012.
  20. ^ Hauser, John R. (März 1996). "Umgang mit Gleitkomma-Ausnahmen in numerischen Programmen". ACM -Transaktionen zu Programmiersprachen und Systemen. 18 (2): 139–174. doi:10.1145/227699.227701. S2CID 9820157.
  21. ^ "Integrierte Ausnahmen-Python 3.10.4 Dokumentation". docs.python.org. Abgerufen 17. Mai 2022.
  22. ^ "Stroustrup: C ++ Style and Technique FAQ". www.strustrup.com. Archiviert Aus dem Original am 2. Februar 2018. Abgerufen 5. Mai 2018.
  23. ^ Bloch, Joshua (2008). "Punkt 57: Verwenden Sie Ausnahmen nur für außergewöhnliche Situationen". Effektiver Java (Zweite Ausgabe). Addison-Wesley. p.241. ISBN 978-0-321-35668-0.
  24. ^ Stroustrup, Bjarne. "C ++ - Stil und Technik -FAQ". www.strustrup.com. Abgerufen 12. Januar 2022.
  25. ^ a b c d Weimer, W; Necula, G.C. (2008). "Außergewöhnliche Situationen und Programmzuverlässigkeit" (PDF). ACM -Transaktionen zu Programmiersprachen und Systemen. Vol. 30, nein. 2. Archiviert (PDF) vom Original am 2015-09-23.
  26. ^ Roberts, Eric S. (21. März 1989). "Implementierung von Ausnahmen in C" (PDF). Dec Systems Research Center. SRC-RR-40. Abgerufen 4. Januar 2022. {{}}: Journal zitieren erfordert |journal= (Hilfe)
  27. ^ Christiansen, Tom; Torkington, Nathan (2003). "10.12. Umgang mit Ausnahmen". Perl Kochbuch (2. Aufl.). Peking: O'Reilly. ISBN 0-596-00313-7.
  28. ^ Stroustrup 1994, 16.6 Ausnahmebehandlung: Wiederaufnahme vs. Terminierung, S. 390–393.
  29. ^ Scott Meyers, Die wichtigste C ++ - Software ... je Archiviert 2011-04-28 bei der Wayback -Maschine, 2006
  30. ^ D. Cameron, P. Faust, D. Lenkov, M. Mehta, "Eine tragbare Implementierung von C ++ Ausnahmehandling", Verfahren der C ++ - Konferenz (August 1992) Usenix.
  31. ^ Peter Kleissner (14. Februar 2009). "Windows -Ausnahmehandling - Peter Kleissner". Archiviert von das Original am 14. Oktober 2013. Abgerufen 2009-11-21., Compiler -basierte strukturierte Ausnahmebehandlung Sektion
  32. ^ Graham Hutton, Joel Wright, "Ausnahmen korrekt zusammenstellen Archiviert 2014-09-11 bei der Wayback -Maschine". Verfahren der 7. Internationalen Konferenz über Mathematik des Programmbaus, 2004.
  33. ^ Lajoie, Josée (März - April 1994). "Ausnahmebehandlung - Unterstützung des Laufzeitmechanismus". C ++ - Bericht. 6 (3).
  34. ^ a b Schilling, Jonathan L. (August 1998). "Optimierung von C ++ Ausnahmehandling". Sigplan merkt. 33 (8): 40–47. doi:10.1145/286385.286390. S2CID 1522664.
  35. ^ "Moderne C ++ Best Practices für Ausnahmen und Fehlerbehandlung". Microsoft. 8. März 2021. Abgerufen 21. März 2022.
  36. ^ a b Stroustrup, Bjarne (18. November 2019). "C ++ Ausnahmen und Alternativen" (PDF). Abgerufen 23. März 2022.
  37. ^ M. Hof, H. Mössenböck, P. Pirkelbauer, "Ausnahmebehandlung mit Zero-Overhead-Ausnahme mit Metaprogrammierung Archiviert 2016-03-03 bei der Wayback -Maschine",", Proceedings Sofsem'97, November 1997, Vorlesungsnotizen in Informatik 1338, S. 423-431.
  38. ^ Alle Ausnahmen werden behandelt, Jim Wilcox, "Alle Ausnahmen werden behandelt". Archiviert vom Original am 2015-03-18. Abgerufen 2014-12-08.
  39. ^ a b c MAC Developer Library, "Unzereinte Ausnahmen Archiviert 2016-03-04 bei der Wayback -Maschine"
  40. ^ Msdn, Appdomain.unhandleDexception Ereignis Archiviert 2016-03-04 bei der Wayback -Maschine
  41. ^ Das Python -Tutorial, "8. Fehler und Ausnahmen Archiviert 2015-09-01 im Wayback -Maschine"
  42. ^ "Java Practices -> Bieten Sie einen unbekannten Ausnahmebehandler.". www.javapractices.com. Archiviert Aus dem Original am 9. September 2016. Abgerufen 5. Mai 2018.
  43. ^ Pymotw (Python -Modul der Woche), ","Ausnahmebehandlung Archiviert 2015-09-15 in der Wayback -Maschine"
  44. ^ "Google Answers: Der Ursprung der überprüften Ausnahmen". Archiviert vom Original am 2011-08-06. Abgerufen 2011-12-15.
  45. ^ Java -Sprachspezifikation, Kapitel 11.2. http://java.sun.com/docs/books/jls/third_edition/html/exceptions.html#11.2 Archiviert 2006-12-08 am Wayback -Maschine
  46. ^ Mössenböck, Hanspeter (2002-03-25). "Erweiterte C#: Variable Anzahl der Parameter" (PDF). Institut Für Systemoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. p. 32. Archiviert (PDF) vom Original am 09.09.2012. Abgerufen 2011-08-05.
  47. ^ a b c Eckel, Bruce (2006). In Java denken (4. Aufl.). Upper Saddle River, NJ: Prentice Hall. S. 347–348. ISBN 0-13-187248-6.
  48. ^ Gunnerson, Eric (9. November 2000). "C# und Ausnahmespezifikationen". Archiviert von das Original am 1. Januar 2006.
  49. ^ a b Bill Venners; Bruce Eckel (18. August 2003). "Das Problem mit überprüften Ausnahmen: Ein Gespräch mit Anders Hejlsberg, Teil II". Abgerufen 4. Januar 2022.
  50. ^ Juneau, Josh (31. Mai 2017). Java 9 Rezepte: Ein Problemlösungsansatz. Apress. p. 226. ISBN 978-1-4842-1976-8.
  51. ^ "Vorteile von Ausnahmen (die Java ™ -Tutorials: Wesentliche Klassen: Ausnahmen)". Download.oracle.com. Archiviert vom Original am 2011-10-26. Abgerufen 2011-12-15.
  52. ^ "Unkontrollierte Ausnahmen - Die Kontroverse (die Java ™ -Tutorials: Wesentliche Klassen: Ausnahmen)". Download.oracle.com. Archiviert vom Original am 2011-11-17. Abgerufen 2011-12-15.
  53. ^ Bloch 2001: 178 Bloch, Joshua (2001). Effektiver Java -Programmiersprachhandbuch. Addison-Wesley Professional. ISBN 978-0-201-31005-4.
  54. ^ a b "Bruce Eckels MindView, Inc: Muss Java überprüfte Ausnahmen haben?". MindView.net. Archiviert von das Original Am 2002-04-05. Abgerufen 2011-12-15.
  55. ^ "Modula -3 - Verfahrenstypen". .cs.columbia.edu. 1995-03-08. Archiviert vom Original am 2008-05-09. Abgerufen 2011-12-15.
  56. ^ a b Bjarne Stroustrup, Die C ++ - Programmiersprache Dritte Edition, Addison Wesley, 1997. ISBN0-201-88954-4. S. 375-380.
  57. ^ Reeves, J.W. (Juli 1996). "Zehn Richtlinien für Ausnahmespezifikationen". C ++ - Bericht. 8 (7).
  58. ^ Sutter, Kraut (3. März 2010). "Reisebericht: März 2010 ISO C ++ Standards Meeting". Archiviert Aus dem Original am 23. März 2010. Abgerufen 24. März 2010.
  59. ^ "OCAMLEXC - Ein nicht erfasster Analysator für objektive CAML". Caml.inria.fr. Archiviert vom Original am 2011-08-06. Abgerufen 2011-12-15.
  60. ^ "Asynchrone Ausnahmen in Haskell - Marlow, Jones, Moran (ResearchIndex)". Citeseer.ist.psu.edu. Archiviert vom Original am 2011-02-23. Abgerufen 2011-12-15.
  61. ^ Freund, Stephen N.; Mitchell, Mark P. "Sichere asynchrone Ausnahmen für Python" (PDF). Abgerufen 4. Januar 2022. {{}}: Journal zitieren erfordert |journal= (Hilfe)
  62. ^ "Java Thread Primitive Abschaltung". Java.sun.com. Archiviert vom Original am 2009-04-26. Abgerufen 2011-12-15.
  63. ^ "Interrupts (die Java ™ -Tutorials> Essentielle Java -Klassen> Parallelität)". docs.oracle.com. Abgerufen 5. Januar 2022.
  64. ^ Felker, reich. "Fadenstornierung und Ressourcenlecks". ewontfix.com. Abgerufen 5. Januar 2022.
  65. ^ Bei den Bedingungen (Ausnahmen) geht es wirklich um (2008-03-24). "An welchen Bedingungen (Ausnahmen) geht es wirklich um". Danweinreb.org. Archiviert von das Original am 1. Februar 2013. Abgerufen 2014-09-18.
  66. ^ "Konditionssystemkonzepte". Franz.com. 2009-07-21. Archiviert von das Original am 2007-06-28. Abgerufen 2011-12-15.
  67. ^ WAGEN. Hoare. "Die alte Kleidung des Kaisers". 1980 Turing Award Lecture
  68. ^ "Häufig gestellte Fragen". Archiviert vom Original am 2017-05-03. Abgerufen 2017-04-27. Wir glauben, dass die Kopplung von Ausnahmen an eine Kontrollstruktur, wie in der Try-Catch-final-idiom, zu einem verwickelten Code führt. Es ermutigt auch die Programmierer, zu viele gewöhnliche Fehler zu kennzeichnen, wie z.
  69. ^ Panik und erholen sich Archiviert 2013-10-24 bei der Wayback -Maschine, Geh wiki
  70. ^ Bendersky, Eli (8. August 2018). "Über die Verwendung und Missbrauch von Panik in Go". Eli Benderskys Website. Abgerufen 5. Januar 2022. Die spezifische Einschränkung besteht darin, dass die Wiederherstellung nur in einem Auflaufcode-Block aufgerufen werden kann, der die Kontrolle nicht an einen willkürlichen Punkt zurückgeben kann, sondern nur die Aufräumarbeiten durchführen und die Rückgabewerte der Funktion optimieren kann.
  71. ^ "Fehlergrenzen". Reagieren. Abgerufen 2018-12-10.
  72. ^ "Vue.js api". Vue.js. Abgerufen 2018-12-10.
  73. ^ "Fehlerbehandlung mit Vue.js". Catchjs. Abgerufen 2018-12-10.

Externe Links