Hallo! Eines meiner C++-Progrämmchen stürzt neuerdings zur Laufzeit ab und schreibt "Gleitkomma-Ausnahme" auf den Schirm (SuSE 8.0. i386, gcc 2.95.3). Kann sich jemand einen Reim drauf machen, was das ist und wie man es findet? Gruß Christoph -- Christoph Maurer - Tux#194235 - christoph-maurer at gmx.de
Christoph Maurer
Eines meiner C++-Progrämmchen stürzt neuerdings zur Laufzeit ab und schreibt "Gleitkomma-Ausnahme" auf den Schirm (SuSE 8.0. i386, gcc 2.95.3).
Zumindest die exakte Meldung wäre nötig, wenn möglich auch die Ausgabe von strace. Sonst müsste man schon die Kristallkugel bemühen.
wie man es findet?
gdb? Philipp
* Am Mit, 01 Okt 2003 schrieb Philipp Thomas:
Christoph Maurer
[1 Oct 2003 17:20:31 +0200]: Eines meiner C++-Progrämmchen stürzt neuerdings zur Laufzeit ab und schreibt "Gleitkomma-Ausnahme" auf den Schirm (SuSE 8.0. i386, gcc 2.95.3).
Zumindest die exakte Meldung wäre nötig, wenn möglich auch die Ausgabe von strace. Sonst müsste man schon die Kristallkugel bemühen.
Eben, das ist die Meldung, eine Ausnahme die geworfen wird, mehr kommt nicht.
wie man es findet?
gdb?
Sicher, ist aber bei Programmen, die ne halbe Stunde (im Terminalfenster) laufen, um an die bewusste Stelle zu kommen, sehr nervig, da das im GDB endlos dauert, zumal die bewusste Stelle im Code vorher ca. 20.000 mal überlaufen wird... Na ja, cout-Debugging hat geholfen, ich habe das Problem gelöst, verstehe aber immer noch nicht, warum die Ausnahme geworfen wurde... Der Code sah so aus (vom Prinzip) unsigned a, b; [a b werden belegt] if ( a > 0 && b/a < 2 && b%a != 0) ... Wenn b und a beide 0 waren, wurde diese seltsame Ausnahme geworfen... Weder erkenne ich den Grund dafür, noch verstehe ich, was das mit Gleitkomma-Zahlen zu tun hat. Gruß Christoph -- Christoph Maurer - Tux#194235 - christoph-maurer at gmx.de
* Am Don, 02 Okt 2003 schrieb Ulrich Walter:
Am Donnerstag, 2. Oktober 2003 09:12 schrieb Christoph Maurer:
if ( a > 0 && b/a < 2 && b%a != 0) ...
^^^ Hier steht dann 0/0, und das ist zumindest in der Mathematik ein unbestimmter Ausdruck...
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage... Das ist exakt der Punkt, den ich nicht verstehe! Gruß Christoph -- Christoph Maurer - Tux#194235 - christoph-maurer at gmx.de
Hallo. am Donnerstag, 2. Oktober 2003 um 10:22 kam u.a. folgendes:
* Am Don, 02 Okt 2003 schrieb Ulrich Walter:
Am Donnerstag, 2. Oktober 2003 09:12 schrieb Christoph Maurer:
if ( a > 0 && b/a < 2 && b%a != 0) ...
^^^ Hier steht dann 0/0, und das ist zumindest in der Mathematik ein unbestimmter Ausdruck...
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage...
Das ist exakt der Punkt, den ich nicht verstehe!
Wieso sollte der Ausdruck unbedingt von links nach rechts abgearbeitet werden? Es gab in einer Newsgroup in der ich mitlese vor ein paar Monaten mal eine Diskussion zu dem Thema - die Reihenfolge kann völlig verschieden sein und ist glaube ich vom Compiler abhängig. Richtig wäre: if ( a > 0 ) { if ( b/a < 2 && b%a != 0) { ... } } Gruß, Albert
Hallo! Albert Scholl wrote:
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage...
Das ist exakt der Punkt, den ich nicht verstehe!
Wieso sollte der Ausdruck unbedingt von links nach rechts abgearbeitet werden? Es gab in einer Newsgroup in der ich mitlese vor ein paar Monaten mal eine Diskussion zu dem Thema - die Reihenfolge kann völlig verschieden sein und ist glaube ich vom Compiler abhängig.
Und auch von Compileroptionen. Bis denne Jürgen -- --------------------------------------------------------------------- Kluge Leute können sich dumm stellen, das Gegenteil ist schwieriger. (Kurt Tucholsky) --------------------------------------------------------------------- IMPORTANT NOTICE: This email is confidential, may be legally privileged, and is for the intended recipient only. Access, disclosure, copying, distribution, or reliance on any of it by anyone else is prohibited and may be a criminal offence. Please delete if obtained in error and email confirmation to the sender. If you use Outlook then please do not put my email address into your address-book so that WHEN you get a virus it won't use my address in the From field. begin LOVE-LETTER-FOR-YOU.TXT.vbs No virus, just text!!!!! Outlook is great! End
* Am Don, 02 Okt 2003 schrieb Albert Scholl:
Hallo.
am Donnerstag, 2. Oktober 2003 um 10:22 kam u.a. folgendes:
* Am Don, 02 Okt 2003 schrieb Ulrich Walter:
Am Donnerstag, 2. Oktober 2003 09:12 schrieb Christoph Maurer:
if ( a > 0 && b/a < 2 && b%a != 0) ...
^^^ Hier steht dann 0/0, und das ist zumindest in der Mathematik ein unbestimmter Ausdruck...
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage...
Das ist exakt der Punkt, den ich nicht verstehe!
Wieso sollte der Ausdruck unbedingt von links nach rechts abgearbeitet werden? Es gab in einer Newsgroup in der ich mitlese vor ein paar Monaten mal eine Diskussion zu dem Thema - die Reihenfolge kann völlig verschieden sein und ist glaube ich vom Compiler abhängig.
Richtig wäre:
if ( a > 0 ) { if ( b/a < 2 && b%a != 0) { ... } }
In B. Stroustroups "Die C++-Programmiersprache" steht: "Die Operatoren Komma (,), logisches Und (&&) und logisches Oder (&&) garantieren, dass ihr linker Operand vor ihrem Rechten ausgewertet wird." Es wird dann weiter erläutert, dass insbesonder der rechts von && stehende Teil nur ausgewertet wird, wenn der linke true ergibt. Das scheint mir dann im gcc evtl. nicht so implementiert zu sein... Gruß Christoph -- Christoph Maurer - Tux#194235 - christoph-maurer at gmx.de
Christoph Maurer schrieb: [...]
In B. Stroustroups "Die C++-Programmiersprache" steht:
"Die Operatoren Komma (,), logisches Und (&&) und logisches Oder (&&) garantieren, dass ihr linker Operand vor ihrem Rechten ausgewertet wird." Es wird dann weiter erläutert, dass insbesonder der rechts von && stehende Teil nur ausgewertet wird, wenn der linke true ergibt.
Das scheint mir dann im gcc evtl. nicht so implementiert zu sein...
Hi, ich habe mich auch immer nach genau dieser Aussage gerichtet und bisher keine Probleme gehabt. Insbesondere bei bei solchen Konstrukten: if (p != 0 && p->isSomething()) { ... } Weiss einer was dazu im ISO Standard steht? Gibt es da vielleicht einen Unterschied zwischen C und C++? Oder kann man diese Auswertereihenfolge vielleicht über Kompileroptionen ändern? Ciao Sebastian
Hi, On Thu, 2 Oct 2003, Albert Scholl wrote:
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage...
Das ist exakt der Punkt, den ich nicht verstehe!
Wieso sollte der Ausdruck unbedingt von links nach rechts abgearbeitet werden?
Weil && einen Sequenzpunkt erzeugt. Damit ist if (cond1 && cond2) { ... } aequivalent zu if (cond1) { if (cond2) { ... } } Ohne ein kongretes Beispiel kann man jetzt leider nicht sagen, ob das nun ein Compilerproblem war, oder nicht. Zur Vermeidung von Division durch 0 reicht eigentlich "if (a > 0 && b/a < 2)" voellig aus.
Es gab in einer Newsgroup in der ich mitlese vor ein paar Monaten mal eine Diskussion zu dem Thema - die Reihenfolge kann völlig verschieden sein und ist glaube ich vom Compiler abhängig.
Nein, nicht bei &&, || oder , Ciao, Micha.
Christoph Maurer schrieb:
* Am Don, 02 Okt 2003 schrieb Ulrich Walter:
Am Donnerstag, 2. Oktober 2003 09:12 schrieb Christoph Maurer:
if ( a > 0 && b/a < 2 && b%a != 0) ...
^^^ Hier steht dann 0/0, und das ist zumindest in der Mathematik ein unbestimmter Ausdruck...
Ja, aber das sollte doch gar nicht mehr ausgewertet werden, da ich vorher auf a>0 abfrage...
Kann es vielleicht sein, dass a > 0 und b / a < 2 parallel ausgewertet werden?
Hi, On Thu, 2 Oct 2003, Christoph Maurer wrote:
Der Code sah so aus (vom Prinzip)
Vom Prinzip, hmm. Damit laesst sich nicht arbeiten.
unsigned a, b; if ( a > 0 && b/a < 2 && b%a != 0) ...
Wenn b und a beide 0 waren, wurde diese seltsame Ausnahme geworfen...
Wenn der Code Tatsache a vor b/a auf != 0 getestet hat (!) dann waere das Werfen von SIGFPE ein Compilerproblem.
Weder erkenne ich den Grund dafür, noch verstehe ich, was das mit Gleitkomma-Zahlen zu tun hat.
Ist nur ne bloede Fehlermeldung. 0/0 erzeugt im Prozessor ne #FP Exception (welche die gleiche ist, die auch bei Fliesskommafehlern erzeugt wird), diese wird auf das signal SIGFPE gemappt, und der default Handler gibt einfach i18n("Floating point exception") aus und teminiert das Programm. Ciao, Micha.
Christoph Maurer
nervig, da das im GDB endlos dauert, zumal die bewusste Stelle im Code vorher ca. 20.000 mal überlaufen wird...
Wenn du das Programm zunächst ohne jeglichen Break- oder Watch-Points startest, ist es unter gdb nicht langsamer (vorausgesetzt du compilierst mit -O2 -g).
Der Code sah so aus (vom Prinzip)
unsigned a, b;
[a b werden belegt]
if ( a > 0 && b/a < 2 && b%a != 0) ...
Vom Prinzip hilft nicht viel :( Für solche Fälle ist sollte es schon der Originalcode sein oder besser noch möglichst kurzer Testcode, mit welchem sich der Fehler reproduzieren lässt. *Dann* wäre eine echte Möglichkeit gegeben, einmal zu prüfen, ob der Compiler falsch optimiert hat oder der Bug im Code liegt. Philipp
participants (8)
-
Albert Scholl
-
Christoph Maurer
-
Jürgen Busse
-
Michael Matz
-
Peter Wiersig
-
Philipp Thomas
-
Sebastian Huber
-
Ulrich Walter