gcc-Ausnahmebestimmung des Standarddestruktors

8
%Vor%

Dieser Code gibt den folgenden Fehler:

%Vor%

auf meinem Debian-Test (gcc (Debian 4.6.0-10) 4.6.1 20110526 (Vorabversion)) kompiliert aber ohne Fehler auf früheren GCC-Versionen (4.5 auf meinem Debian-System wieder).

Wie wirkt sich eine Ausnahmebedingung auf das Überschreiben virtueller Destruktoren aus? Entsprechend dieser Antwort soll der Compiler einen Standardkonstruktor erstellen, der der throw-Deklaration der Basisklasse entspricht. Offensichtlich passiert dies nicht auf dem neuen gcc. Was hat sich geändert, was ist das richtige Verhalten des Compilers und gibt es eine einfache Lösung für das Problem als das manuelle Hinzufügen leerer Destruktoren in abgeleiteten Klassen (Compiler-Flag zum Beispiel).

    
Yordan Pavlov 30.06.2011, 17:56
quelle

2 Antworten

3

Ich nehme an, dass im realen Code entweder ~A() oder ~B() als virtuell deklariert wird? (Die Fehlermeldung beschwert sich über einen virtuellen Destruktor, aber im geschriebenen Code ist keiner der Destruktoren virtuell.)

Ich glaube, dass die virtuelle Vererbung das Problem auslöst. Der (implizit definierte) Destruktor von C muss zuerst ~B() aufrufen und dann, weil C die am weitesten abgeleitete Klasse ist, ~A() aufrufen. (12.4 / 6)

Die generierte Ausnahmespezifikation für ~C() ist erforderlich, damit eine beliebige Ausnahme weitergegeben werden kann, da sie direkt ~A() aufruft, die keine Ausnahmebedingung hat. (15.4 / 13)

Und das löst dann Ihren Fehler aus - Sie können eine virtuelle Funktion mit einer throw() Spezifikation (Destruktors von B) nicht mit einer Version überschreiben, die sie werfen könnte. (15.4 / 3)

Die Lösung wäre, throw() auf Destruktor von A zu setzen. (Wenn du das nicht kannst, warum machst du das dann auf B?)

Der Fehler würde auch ohne die virtuelle Vererbung nicht passieren - weil der Destruktor von C dann nur den Destruktor von B aufrufen würde. (Bs Destruktor würde immer noch A's nennen - und du bist immer noch auf dünnem Eis unterwegs, denn wenn A's Destruktor wirft, gehst du direkt zu terminate() .)

    
Alan Stokes 19.07.2011, 21:19
quelle
0

GCC 4.X ist strenger als frühere Versionen und kann es daher nicht implizit angeben. Versuchen Sie es ausdrücklich anzugeben.

So wie ich es verstehe, wenn Klasse B einen Destruktor hat, der explizit nichts wirft (zB.

%Vor%

Es sollte in Ordnung sein.

Unabhängig davon, als ich das letzte Mal nachgesehen habe, war es sehr schlecht, Ausnahmen von d'ors zu werfen.

Hoffe, dass dir das hilft!

    
Syndacate 30.06.2011 18:26
quelle

Tags und Links