Wie ermittelt die C ++ - Laufzeit den Typ einer ausgelösten Ausnahme?

8

Wenn ich Folgendes tue, wie bestimmt die Laufzeit den Typ der ausgelösten Ausnahme? Verwendet es RTTI dafür?

%Vor%

Siehe auch:

  

Wie wird die C ++ - Ausnahmebehandlung implementiert?

    
codymanix 14.06.2009, 17:27
quelle

2 Antworten

7

Anders als bei den anderen Fragen kann die Antwort auf diese Frage vollständig anhand des Standards beantwortet werden. Hier sind die Regeln

  

Ein Handler ist eine Übereinstimmung für ein Ausnahmeobjekt vom Typ E wenn

     
  • Der Handler ist vom Typ cv T oder cv T & amp; und E und T sind vom gleichen Typ (ignorieren die CV-Qualifikationsmerkmale der obersten Ebene) oder
  •   
  • der Handler ist vom Typ cv T oder cv T & amp; und T ist eine eindeutige öffentliche Basisklasse von E oder
  •   
  • Der Handler ist vom Typ cv1 T * cv2 und E ist ein Zeigertyp, der durch einen oder beide Typen in den Typ des Handlers konvertiert werden kann      
    • eine Standardzeigerkonvertierung (4.10), die keine Konvertierungen in Zeiger auf private oder geschützte oder mehrdeutige Klassen beinhaltet
    •   
    • eine Qualifizierungskonvertierung
    •   
  •   

[Anmerkung: Ein throw-Ausdruck, der ein ganzzahliger konstanter Ausdruck des Integer-Typs ist, der zu Null ausgewertet wird   passt nicht zu einem Handler vom Zeigertyp; das heißt, die Null-Zeiger-Konstantenkonvertierungen (4.10, 4.11) nicht   sich bewerben. ]

Da ich mir nicht ganz sicher bin, wie gut Sie den Standard verstehen, werde ich dies unerklärt lassen und auf Ihre Fragen antworten.

In Bezug darauf, ob RTTI verwendet wird oder nicht - nun, der Typ des ausgelösten Ausnahmeobjekts ist der statische -Typ des Ausdrucks , den Sie an die throw -Anweisung übergeben (vor einiger Zeit) , ich hatte Spaß daran, dies in GCC herauszufinden). Daher muss die Laufzeittypidentifikation nicht durchgeführt werden. So passiert es mit g++ , dass an der Seite, auf der% code_% erscheint, ein throw -Objekt übergeben wird, das den Typ des Ausnahmeobjekts, das Objekt selbst und eine Destruktorfunktion darstellt.

Es wird dann geworfen und Frames werden nach einem passenden Handler durchsucht. Mit Hilfe von Informationen, die in großen Tabellen gefunden wurden (in einem Abschnitt namens std::type_info ) und unter Verwendung der Rücksprungadresse, sieht es aus, welche Funktion für die nächste Behandlung verantwortlich ist. In der Funktion wird eine Persönlichkeitsroutine installiert, die feststellt, ob die Ausnahme behandelt werden kann oder nicht. Diese ganze Prozedur wird in dem Itanium C ++ ABI (implementiert durch G ++), das durch @ PaV verbunden ist, beschrieben (und natürlich detaillierter).

Also, zum Schluss

%Vor%

und

%Vor%

Behandeln Sie nicht den gleichen Typ, natürlich.

    
Johannes Schaub - litb 14.06.2009, 18:20
quelle
4

Es gibt keine Spezifikation für die Implementierung. Eine Implementierung muss dem Standard folgen und es gibt keine Einschränkungen, wie dies erreicht wird. Und es gibt mehr als eine Implementierung, sogar für einen Compiler.

Sie können hier ein Beispiel für eine solche Implementierung lesen:

Itanium C ++ ABI: Ausnahmebehandlung

    
PaV 14.06.2009 17:47
quelle