2010-12-10 5 views
14

Wenn ich ein neues Projekt in nicht verwaltetem C++, Visual Studio 2008 oder höher erstelle, mit welchem ​​Ausnahmebehandlungsmodell möchte ich gehen?Visual C++ nicht verwalteten Code: Verwenden Sie/EHa oder/EHsc für C++ - Ausnahmen?

Ich verstehe, dass/EHa-Option führt zu weniger effizienten Code und fängt auch SEH-Ausnahmen, oder?

Also habe ich von dieser Option entfernt und in der Regel mit/EHsc gehen, so dass ich nur C++ Ausnahmen fangen, die tatsächlich geworfen werden und Zugriffsverletzungen und andere strukturierte Ausnahmen nicht fangen, (...) Handler. Wenn es in meinem Code eine Zugriffsverletzung gibt, möchte ich nicht, dass sie von einem Catch (...) {} maskiert wird.

Ich Code mit anderen, die wollen (...) {} nichts zu tun und sie wollen es auch tun, wenn es eine Zugriffsverletzung, die für mich eine wirklich schlechte Idee scheint. Wenn es einen Fehler aufgrund schlechter Codierung gibt, wollen Sie nicht Ihre Finger in die Ohren stecken und laut "La la la la la!" damit Sie das Programm nicht abstürzen müssen? Wenn der Code aufgrund eines Codierungsfehlers jetzt in einem schlechten Zustand ist, möchten Sie, dass der Code tatsächlich fortgesetzt wird?

Also mein allgemeiner Gedanke ist, dass/EHa größeren/langsameren Code erstellt und es Programmierern erlaubt, mit dem Schreiben von Code, dass wenn ein schwerwiegender Fehler vorhanden ist, es weiterhin in einem undefinierten Zustand ausgeführt wird.

BTW, ich spreche über Anwendungen und Service-Code, die wir zum größten Teil schreiben. Nicht Low-Level-Gerätetreiber oder ähnliches.

Bitte berücksichtigen Sie Ihre Gedanken.

Antwort

16

/EHa macht zwei Dinge. In erster Linie unterdrückt es eine Optimierung, die Ausnahmefilter auslässt, die die Destruktoren der lokalen Klassenvariablen automatisch aufrufen, wenn der Code-Analysator keinen Code sehen kann, der eine C++ - Ausnahme auslösen könnte. Dies macht die Stapelabwickelung für jede Art von Ausnahme sicher, nicht nur für eine C++ - Ausnahme. Overhead für diese Ausnahmefilter ist Zeit auf x86 und Speicherplatz auf x86 und x64.

Und ja, es ändert das Verhalten von catch (...), es filtert jetzt auch jede SEH-Ausnahme, nicht nur C++. Dies ist in der Tat ein Glücksspiel, weil Sie all die wirklich fiesen Sachen, die asynchronen Hardware-Ausnahmen, fangen. Obwohl ich persönlich nicht glaube, dass das Einfangen aller C++ - Ausnahmen auch sehr vertretbar ist, haben Sie immer noch eine vage Idee, in welchem ​​Maße der Programmstatus mutiert wurde und warum er fehlgeschlagen ist.

Realistisch, müssen Sie zu __try/__except wechseln, damit Sie Ihren eigenen Ausnahmefilter schreiben können und vermeiden, die schlechten zu fangen. Der Ausnahmecode für C++ - Ausnahmen ist 0xe04d5343 ("MSC"). Using _set_se_translator() wäre ein anderer Ansatz.

4

Ich benutze/EHa, weil es mit .NET Interop sicher ist, während/EHsc nicht sein kann; siehe zum Beispiel Destructors not called when native (C++) exception propagates to CLR component.

Wenn jedoch für eine bestimmte Bit-Code die zusätzliche Leistung wirklich wichtig ist und Sie .NET (oder was auch immer sonst) Kompatibilität nicht benötigen, dann sicher,/EHsc klingt gut.

Weder/EHsc nor/EHa fangen die meisten Speicherfehler, so dass diese zu verwenden, um Zugriffsverletzungen zu fangen ist ein hoffnungsloser Fall.

+2

Sie sollten niemals versuchen, Zugriffsverletzungen in jedem Fall zu erfassen. –

+1

Das ist mein Verständnis ... aber ich habe Leute schreiben fangen (...) {} und wenn/EHa ausgewählt ist, dann würde das die Zugriffsverletzung begraben, glaube ich. Es ist eine Sache zu fangen (...) {cleanup_stuff; werfen; } Aber selbst in diesem Fall, wenn es sich um eine Zugriffsverletzung handelt, bist du sicher, dass cleanup_stuff es tun wird? Du bist in einem schlechten Zustand, also würde ich wahrscheinlich denken, dass das Programm am besten ist, wenn man dort abstürzt. – MarkS

+3

Ich arbeite an einem Client/Server-System, wo, wenn der Server eine Ausnahme (idealerweise jede Ausnahme, einschließlich Zugriffsverletzung) hat, möchte ich die Ausnahmebedingungsnachricht an den Client senden, bevor der Server-Thread abstürzen. Andernfalls reagiert der Server nicht mehr. –

Verwandte Themen