šHgeocities.com/Vienna/Stage/4793/excp5.htmgeocities.com/Vienna/Stage/4793/excp5.htmdelayedx׸ÕJ˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙Č0¤£OKtext/html€Cmo˙˙˙˙b‰.HMon, 18 Dec 2000 15:42:02 GMTåMozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)en, *׸ÕJ Die Ausnahmespezifikation

Zurück ] Nach oben ] Weiter ]

 

Die Ausnahmespezifikation

Einerseits aus Dokumentationsgründen, andererseits auch zur Möglichkeit der Begrenzung der Exceptions, die eine Funktion wirft, gibt es die Möglichkeit in der Funktionsdeklaration die Menge ans Exceptions zu spezifizieren. Dies gibt dem Aufrufer die Garantie, daß nur diese Exceptions bzw. von diesen abgeleitete geworfen werden. Wird innerhalb der Funktion diese Garantie gebrochen, so wird std::unexcepted() aufgerufen, welches normalerweise abort() aufruft.

Die könnte wie folgt aussehen:

void f() throw (x2, x3)

welches gleichbedeutend ist mit:

void f()
try  
{ 
    ...
}
catch (x2) { throw; } // weiterwerfen
catch (x3) { throw; } // weiterwerfen
catch (...) {
    std::unexpected(); // = abort()
}

Gibt man keine Spezifikation an, so wird angenommen, dass die Funktion jede Ausnahme werfen kann. Mit einer leeren Liste, also throw(), sagt man, dem Compiler, dass diese Funktion keine Exception wirft. Dies kann in gewissen Funktionen einen kleinen Vorteil bringen, da der Compiler für diese keine zusätzlichen Exceptionstrukturen anlegen muß.

Hinweise:

Bei der Implementation der Funktionen ist ggf. die Ausnahmespezifikation mit anzugeben.

Bei virtuellen Funktionen ist es so, dass sie nur von Funktionen überschrieben werden  können, die mindestens genauso restriktiv wie ihre eigene Ausnahmespezifikation ist. Einschränkungen sind hierbei erlaubt.

Exceptions & Performance

Generell kann gesagt werden, dass ein Programm mit Exceptions, welches aber keine einzige auswirft, keinerlei Mehraufwand in der Laufzeit erzeugt. Natürlich vergrößert sich das Programmodul, da zusätzliche Kontrollstrukturen angelegt werden und Funktionen eingelinkt werden. Diese Vergrößerung bewegt sich im Rahmen von 20 - 100 kByte.

Sobald aber Exceptions ins Spiel kommen, kostet das etwas über einen Funktionsaufruf und dem Code der Fehlerbehandlung. Wenn man aber bedenkt, dass bei den traditionellen Methoden der Code für die Fehlerbehandlung und für die Verwaltung, sprich Abfrage jedes Codes usw., zu programmieren ist, so ist man mit dem Exceptionhandling auf jeden Fall besser beraten, da man die Verwaltung dem überlässt, der dafür konzipiert ist, dem Rechner.

Wie schon erwähnt, kann es eine Performanceverbesserung geben, wenn man bei Funktionen, die keine Ausnahme werfen, die Spezifikation throw() angibt. Dies ist besonders bei reinen C-Funktionen angeraten.

Da man Ausnahme nicht nur für die Fehlerbehandlung, sondern auch Alternativen Return-Mechanismus verwenden kann, könnte es einen gewissen Charme haben, diese für normale Abläufe zu "mißbrauchen", wie z.B. die Sonderbehandlung einer leeren Liste, die dann im catch-Handler stattfindet. Doch auch hier sollte man wegen der Effizienz besser lokale Kontrollstrukturen wie for oder if einsetzen. An den Stellen,  wo man aber sowieso einen Funktionsaufruf "bezahlen" muß, also z.B. in stark rekursiven Funktionsaufrufen beim Durchsuchen einer Baumstruktur, kann es eleganter sein, dies mit dem Exceptionhandling zu realisieren.