Das abfangen von Division durch null-Fehler in Visual Studio 2008 C++?
Wie kann ich catch a divide-by-zero-Fehler (und nicht andere Fehler; und um Zugang zu Informationen über die Ausnahme) in Visual Studio 2008 C++?
Habe ich versucht, dieses:
try {
int j=0;
int i= 1/j;//actually, we call a DLL here, which has divide-by-zero
} catch(std::exception& e){
printf("%s %s\n", e.what());
} catch(...){
printf("generic exception");
}
Aber das geht der generic ... catch-block. Ich verstehe, dass die MS-spezifischen __try kann nützlich sein, hier irgendwie, aber ich würde lieber C++ - standard, und in jedem Fall habe ich Destruktoren, die verhindern, dass die Verwendung von __versuchen.
KLARSTELLUNG: Der obige code ist vereinfacht, für die Erläuterung. Eigentlich ist die Division durch null ist ein Fehler, der sich tief in eine Drittanbieter-DLL, für die ich nicht den source-code. Der Fehler hängt vom parameter (ein handle zu einer komplexen Struktur), die ich übergeben, um die Bibliothek, aber nicht in einer offensichtlichen Weise. Also, ich möchte in der Lage sein zu erholen würdevoll.
- nicht Division durch null?
- "Ich würde es vorziehen, standard-C++" dann müssen Sie es vorziehen, nicht durch null zu dividieren, denn das ist Undefiniertes Verhalten. Es ist Plattform-spezifisch, dass es eine Ausnahme auslöst, an alle, es ist also keine große Zumutung, wenn die Mittel des fangs, es ist auch Plattform-spezifische. Auf Plattformen, wo eine Division durch null nicht werfen, Sie nicht wiederherstellen dieser Fehler in der dll, so dass Sie nicht brauchen eine Plattform-unabhängige Mittel der Erholung.
- Jessop die In dem realen Beispiel die Division durch null ist tief in einer DLL, für die ich nicht den source-code.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, dass man nicht einfach beheben Sie die Ursache der Ausnahme der code-Generierung (vielleicht, weil Sie nicht den source-code, die Besondere Bibliothek, und vielleicht, weil Sie nicht passen Sie die input params, bevor Sie ein problem verursachen).
Müssen Sie springen durch einige Reifen um diese Arbeit zu machen, wie Sie möchte, aber es kann getan werden.
Zuerst müssen Sie installieren eine Strukturierte Ausnahmebehandlung übersetzung Funktion durch Aufruf
_set_se_translator()
(siehe hier) dann untersuchen Sie den code, den Sie sind, übergeben, wenn ein SEH-Ausnahme tritt auf, und werfen eine entsprechende C++ - Ausnahme.Dann können Sie fangen Ihre
CMyFunkyDivideByZeroException()
in C++ in der üblichen Weise.Beachten Sie, dass zu installieren, müssen Sie Ihre exception-translation-Funktion auf jeden thread, den Sie möchten Ausnahmen übersetzt.
_set_se_translator
arbeitet auf einer per-thread-basis und ist nur sinnvoll, wenn Sie Steuern die Erstellung von all threads. Am ehesten fällt auf die Füße beim aufrufen von DLLs. Kann man nicht einfach übersetzen Sie Ihre SEHs. Zum Beispiel eine Excel-C-AddIn-DLL kann daher leicht stürzt das ganze Excel-Prozess. Nur eincatch(...)
- block zu fangen - aber weder Sie noch Excel weiß, welche SEH war gefangen. Es könnte einEXCEPTION_ACCESS_VIOLATION
(aliasSIGSEGV
auf andere OSs), in dem Fall bist du verdammt sowieso. Ich denke_set_se_translator
erzeugt ein Falsches Gefühl von Sicherheit.EXCEPTION_ACCESS_VIOLATION
ist das Spiel noch nicht vorbei, unbedingt - das OS ist einfach sagen Sie, dass Sie keinen Zugriff auf den Speicher.catch(...)
natürlich wissen Sie nicht, was der Typ ist. Sowieso... es sei denn Ihr Programm ist ein debugger, spyware oder ein virus, warum würden Sie jemals auf den Speicher zugreifen, die Sie nicht besitzen? In den meisten Fällen das Programm ist schlecht. Selbst bei einem "harmlosen" NULL-pointer-Zugriff auf das Programm kann nicht fortgesetzt werden, weil es wird wieder Abstürzen.C++ behandelt nicht die Division durch null eine Ausnahme, pro-se.
Zitieren Stroustrup:
"The Design and Evolution of C++" (Addison Wesley, 1994)
In jedem Fall, Ausnahmen sind nie ein Ersatz für richtige Voraussetzung Handhabung.
Fangen Division durch null-von Ausnahmen in Visual C++ try->catch (...) nur aktivieren /EHa-option in den Projekteinstellungen. Sehen Projekt-Eigenschaften -> C/C++ -> Code-Generation -> Ändern Sie die Enable C++ Exceptions "ja Mit SEH Ausnahmen". Das ist es!
Details finden Sie hier:
http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs. 80).aspx
Können Sie entweder verwenden die structured exception handling (mit __try etc.) oder Sie können installieren Sie eine structured exception handler übersetzer: _set_se_translator
Beide sind Betriebssystem-spezifisch.
Kann man das nicht mit standard C++, da es nicht standard-C++ - Ausnahme. Es ist eine strukturierte Ausnahme. Für die standard-C++ - Ausnahme jemand hat zu tun, eine
throw exception;
aus dem code.Warum nicht prüfen, ob diese vor? Die Leistung ist trivial für eine einfache
j == 0
im Vergleich zum Kontext-switching für die Ausnahmebehandlung.Versuchen Sie den folgenden code:
Natürlich, wenn Sie OK sind, dies zu tun, ohne Ausnahmen, die man tun könnte:
Bearbeiten, die in Reaktion auf Aufklärung: Sie muss herausfinden, welcher Eingang es ist, dass Sie die übergabe der Dritten Partei, die Sie verursacht, durch null zu teilen, bevor die hand, und Griff, noch bevor Sie überhaupt den Aufruf Ihrer Funktion.
Ist ein guter Ansatz wäre, um sichere Objekt-orientierten Wrapper wie SafeInt. Es auch scheint integriert zu sein in Visual Studio 2010.
update:
Wenn die division durch null passiert im code von Drittanbietern ist Ihre einzige option ist SEH oder etwas vergleichbares als beantwortet von Seb Rose