Integer division by zero - Wie fängt man diese exception?
-
Hallo,
ich habe gerade angefangen mich etwas mit try und catch() zu beschäftigen und bin dabei auf die Exception "division by zero" gestoßen. Im Tutorial [ http://www.willemer.de/informatik/cpp/exceptions.htm ] steht sie lässt sich zB mit catch(...) abfangen:int main() { try { int a=0; int b=5/a; } catch(...) { cout<<"Ausnahme\n"; } }bei mir führt dieser Codeschnipsel aber zum Programmabsturz und MS Visual C++ 2008 EE sagt "Unbehandelte Ausnahme : Integer division by zero";
woran liegt das? muss ich am compiler etwas umstellen oder lässt sich die exception "division by zero" irgendwie anders abfangen?
danke schonmal,
andi01.
-
Warum try-catch? Bei sowas simplen kann man doch auf einfach mit einer if-Abfrage auf 0 prüfen.
-
klar ich mache das eigentlich nur zu Übungszwecken, man muss ja erst mal einfach anfangen mit try und catch
außerdem ist es (wenn man mehrere divisionen macht) doch eigentlich einfacher einmal try und catch zu schreiben als bei jeder division den divisor auf 0 zu prüfen oder?
-
Naja dann kannst du es so machen, wie es ein bisschen weiter unten steht.
int main() { int a = 5; int b = 0; try { if(b == 0) { throw 0; } a = a / b; } catch(...) { std::cout << "Division bei 0 ist nicht erlaubt"; } }
-
Division by Zero ist eine SEH-Exception, eine Windows Interne Exception (hardware exception wenn man so will).
Der VC++ faengt diese nicht automatisch. Siehe auch: Structured Exception Handling und Microsoft Visual C++ and Win32 Structured Exception Handling.
Schnelle Loesung:
mit/EHskompilieren
-
Diese Division ist undefiniertes Verhalten, demnach wird auch keine Exception von der C++ Runtime geworfen, sondern vmtl. ein Hardwarefehler auftreten. (oder was auch immer).
-
Zu Übungszwecken noch mehr lustige Sachen mit Exceptions
Google: c++ exception destruktor
http://www.gotw.ca/gotw/059.htm
-
Da ist C# und .NET zum Glück ein bisschen weiter und hat eine DividiByZeroException und fängt das ab

-
das heißt diese "hardware exception" lässt sich in C++ gar nicht abfangen oder? die einzige alternative ist dann wohl vor jeder division den divisor auf 0 zu prüfen.
danke euch allen,
andi01.
-
> Da ist C# und .NET zum Glück ein bisschen weiter
Nicht weiter, nur höher. Das geht alles auf Kosten der Performance.

-
Soviel Performance geht nun auch wieder nicht drauf

-
Es summiert sich. Ich will keine managed vs. unamanaged-Orgie starten, aber das ist eine der Vorzüge durch die VM.
-
Ich meine nur, mit C# kann man leicht wenig Code schreiben, aber viel erzielen und ich schreib gerne wenig Code :p
-
andi01 schrieb:
das heißt diese "hardware exception" lässt sich in C++ gar nicht abfangen oder? die einzige alternative ist dann wohl vor jeder division den divisor auf 0 zu prüfen.
Je nach Compiler ist das schon moeglich.
Beim VC++ setzt die Option /EHs zB das Exception Model auf "Synchron", dh SEH und C++ Exception werden gleich behandelt.
-
und wo genau muss man diese option einstellen? das wäre jedenfalls was ich suche danke

edit: ich benutze Microsoft Visual C++ 2008 Express Edition unter Windows Vista
-
so ich habe es jetzt durch probieren selbst rausgefunden

für alle die dasselbe Problem haben: unter Projekteigenschaften>Konfigurationseigenschaften>C/C++>Codegenerierung im Feld C++-Ausnahmen aktivieren von "Ja(/EHsc)" entweder auf "Ja bei SEH-Ausnahmen(/EHa)" oder auf "Nein" stellen.
danke an alle für die Hilfe,
andi01.
-
andi01 schrieb:
das heißt diese "hardware exception" lässt sich in C++ gar nicht abfangen oder? die einzige alternative ist dann wohl vor jeder division den divisor auf 0 zu prüfen.
Nein. Besser ist, es gar nicht soweit kommen lassen.
Ich kann mir nicht viele Anwendungsfälle vorstellen, in denen eine Division durch 0 kein Programmierfehler ist und sinnvoll behandelt werden kann. Meist steckt eine höhere Logik dahinter (z.B. wenn ich etwas an alle Mitglieder einer Gruppe verteilen möchte und sich keine Mitglieder registriert haben). Dann kann man auch Exceptions auf höherer Ebene werfen; "NoMembers" sagt mehr aus als "DivisionByZero". Oder sogar nur Assert bei reinen Programmierfehlern.
Bevor du dich mit SEH-Ausnahmen von Standard-C++ entfernst, solltest du das vielleicht nochmals überdenken.
-
Ich kann mir nicht viele Anwendungsfälle vorstellen, in denen eine Division durch 0 kein Programmierfehler ist und sinnvoll behandelt werden kann
stimmt
eigentlich wollte ich mich ja auch nur in try und catch() etwas einarbeiten, da hatte ich wohl ein etwas unglückliches Beispiel gewählt 
danke euch allen,
andi01.