Warum werden meine C ++ - Ausnahmen nicht abgefangen?

8

Ich habe C ++ Code, der ein sehr standardmäßiges Ausnahmemuster verwendet:

%Vor%

Das Problem ist, dass die Ausnahmen nicht abgefangen werden und ich nicht herausfinden kann, warum.

Der Code wird in einer statischen Bibliothek in OS X (über Xcode) kompiliert. Die Bibliothek ist in eine Cocoa-Anwendung eingebunden, wobei ein Aufruf der betreffenden Funktion über ein Objective-C ++ - Thunk erfolgt. Ich vermute, dass das Zusammenspiel zwischen Objective-C und C ++ der Schuldige ist, aber alle meine Versuche, dies festzuhalten, sind fehlgeschlagen.

Ich konnte kein einfaches Beispiel erstellen, das dieses Verhalten in einem einfachen Beispiel reproduziert. Wenn ich den relevanten Code aus dem Kontext meines großen Programms herausnehme, funktioniert alles.

Kann jemand vorschlagen, warum meine Ausnahmen nicht gefangen werden?

    
gauss256 04.09.2009, 06:03
quelle

8 Antworten

-2

Danke für den Beitrag von allen. Das sind gute Vorschläge für jeden, der auf ein ähnliches Problem stößt. Es funktioniert jetzt, aber ich bin mir nicht 100% ig sicher, welche der verschiedenen Veränderungen, die ich gemacht habe, die Dinge wieder gesund werden ließen. Wieder einmal hat sich die Herangehensweise, sich zu etwas zu vereinfachen, das von dort aus arbeitet und baut, bezahlt gemacht.

Eine Sache, die in den Antworten nicht erwähnt wurde und die meiner Meinung nach Teil meiner Verwirrung war, besteht darin, dafür zu sorgen, dass der Behandler deutlich macht, dass er tatsächlich die Ausnahme erfasst hat. Ich denke, dass in einigen meiner Formulierungen der Handler diese Tatsache maskierte und die Ausnahme an einen höheren Handler weitergab.

    
gauss256 04.09.2009, 20:56
quelle
16

C ++ bietet Ihnen eine Vielzahl von Optionen zum Abfangen: Wert, Referenz oder Zeiger. Beachten Sie, dass dieser Code nur std :: exceptions erfasst, die durch Verweis oder Wert übergeben werden:

%Vor%

Wahrscheinlich wird die Ausnahme vom Zeiger übergeben:

%Vor%

Überprüfen Sie den Code, der die Ausnahme auslöst, und sehen Sie, wie es geht.

Wie Mark hervorhebt, riskieren Sie, wenn Sie nach Wert anstatt nach Referenz suchen, Ihr Objekt zu schneiden.

    
Bill 04.09.2009 15:28
quelle
15

Probieren Sie einen catch(...) {} -Block aus, sehen Sie, ob wirklich eine Ausnahme ausgelöst wird.

    
Michael Foukarakis 04.09.2009 06:08
quelle
7
  

Ich vermute, dass das Zusammenspiel zwischen Objective-C und C ++ der Schuldige ist, aber alle meine Versuche, dies festzuhalten, sind fehlgeschlagen.

Sie haben wahrscheinlich Recht, obwohl es schwer zu finden ist.

Erstens, GCC explizit erlaubt es Ihnen nicht Exceptions in Objective C ++ werfen und in C ++ abfangen ("Wenn das Objective-C-Exception-Modell aus Objective-C ++ verwendet wird, funktioniert es derzeit nicht mit C ++ - Exceptions. Das bedeutet, dass @throw keine Exception von Objective sein kann -C und catch it in C ++ oder umgekehrt (zB throw ... @catch ). ")

Ich denke jedoch, dass Sie einen Fall beschreiben, in dem Objective C ++ C ++ - Code aufruft, der C ++ - Code wirft und Sie hoffen, dass C ++ - Code die Ausnahme abfängt. Leider habe ich Schwierigkeiten, Dokumentation für diesen speziellen Fall zu finden. Es gibt etwas Hoffnung, weil " Es wird geglaubt, um sicher zu sein Wirf eine C ++ - Ausnahme von einer Datei durch eine andere Datei, die für das Java-Ausnahmemodell kompiliert wurde, oder umgekehrt, aber in diesem Bereich könnten Fehler auftreten . " Wenn sie es für Java tun können, gibt es eine Chance, dass sie es für Objective C ++ tun können.

Zumindest müssen Sie -fexceptions zur Kompilierzeit (" müssen Sie diese Option möglicherweise aktivieren, wenn C-Code kompiliert wird, der ordnungsgemäß mit in C ++ geschriebenen Ausnahmeroutinen zusammenarbeiten muss). Auch hier wird Objective C ++ nicht explizit erwähnt, aber es kann zutreffen.

    
Max Lybbert 04.09.2009 08:15
quelle
5

Eine wenig bekannte gotcha mit Ausnahmen bezieht sich auf den Zugriff der Basisklasse.

Wenn Sie tatsächlich eine Klasse werfen, die privat von std::exception abgeleitet wird, wird der std::exception -Handler nicht ausgewählt.

Zum Beispiel:

%Vor%

Gewöhnlich würde eine solche Reihenfolge von Handlern dazu führen, dass der 'B' Handler nie ausgewählt wird, aber in diesem Fall 'kommt' B 'privat von' A 'und der catch-Handler für den Typ' A 'wird nicht berücksichtigt.

    
Richard Corden 04.09.2009 08:25
quelle
3

Ich kann zwei Theorien anbieten:

  1. die Ausnahme wird abgefangen, bevor sie Ihre catch-Klausel erhält; jede Funktion auf dem Stapel könnte der Schuldige sein. Wie Michael vorschlägt, versuche alles zu fangen.
  2. Beim Auflösen der Ausnahme
  3. kann der Handler nicht gefunden werden. Um dies genauer zu analysieren, müssten Sie den Ausnahme-Abwicklungscode durchlaufen, der sehr haarig ist. Sehen Sie, ob das Kompilieren des Objective-C-Codes mit -fobjc-exceptions hilft.
Martin v. Löwis 04.09.2009 06:12
quelle
1

Dies könnte eine lange Geschichte sein, aber in den Compilereinstellungen von Visual Studio gibt es eine Option, um Ausnahmen vollständig auszuschalten. Vielleicht gibt es in GCC / XCode etwas ähnliches.

    
Adrian Grigore 04.09.2009 06:40
quelle
0

C ++ - Ausnahmen können fast alles sein, ziemlich oft ein char* . Wie zuvor vorgeschlagen, fügen Sie catch (...) hinzu, um es zumindest zu unterbrechen und zu sehen, was vor sich geht.

    
Igor Zevaka 04.09.2009 06:44
quelle