"ungültige Gleitkommaoperation" in Funktion, die nichts berechnet
-
Hat sich erledigt, hab den Fehler gefunden, statt
double setCoverPreviousYear(double cover);hätte es
void setCoverPreviousYear(double cover);heißen müssen.
Jetzt läufts. Komisch, mit sowas hab ich nicht gerechnet... Na ja, dann bis zum nächsten Fehler...
Danke jedenfalls für Eure Mühe!
-
ist nen sicheres zeichen, den compiler zu wechseln, wenn du bei so was nich ma ne warnung erhältst - normalerweise sollte es so gar nen fehler geben...
bb
-
unskilled schrieb:
ist nen sicheres zeichen, den compiler zu wechseln, wenn du bei so was nich ma ne warnung erhältst
Das ist vielmehr ein Indiz, daß du mal auf Warnungen achten solltest. C++Builder emittiert in diesem Fall nicht zu Unrecht W8070.
-
öhmmm,... hab ich tomaten auf den Augen? Warum geht es denn mit void als Rückgabewert anstatt double als einzige Änderung?
OK, es wird kein Wert zurückgegeben trotz double-return-typ, aber er wird ja auch nciht benutzt beim Aufruf, also ignoriert. Warum stürzt es dann ab?
-
Maxi schrieb:
Warum stürzt es dann ab?
Weil undefiniertes Verhalten und so...
bb
-
was?
double foo(double x) { // tu nichts } int main() { foo(42.42); }ist undefiniertes Verhalten?
-
Soweit ich weiß, ist das tatsächlich undefiniert.
Technische Ursache des Fehlers ist, daß BCC Gleitkomma-Rückgabewerte über den FPU-Stack zurückgibt. Für folgenden Code
double foo (void) { return 0.0; } int main (void) { foo (); }generiert BCC das:
@@foo$qv proc near ?live16385@0: @1: fld qword ptr [@2] @4: @3: ret align 4 @2: db 0,0,0,0,0,0,0,0 ... @_main proc near ?live16386@0: @5: call @@foo$qv fstp st(0) // <-- xor eax,eax @7: @6: retWenn foo() keinen Wert zurückgibt, wird natürlich auch nie fld aufgerufen, und der Aufruf von fstp invalidiert den FPU-Stack-Pointer.
-
audacia schrieb:
Soweit ich weiß, ist das tatsächlich undefiniert.
double foo (void) { return 0.0; } int main (void) { foo (); }Was?
Ich kann mir nicht vorstellen, dass das undefiniert sein soll. Dann dürfte ja sowas hier auch nicht gehen:int main() { printf("hallo"); }Printf gibt auch was zurück, was ich aber in dem Fall ignoriere. Und das ist doch sicherlich nicht undefiniert, oder? Meiner Meinung nach kann man doch Returnvalues einfach ignorieren, wenn man sie nciht braucht, oder?
Oder ist das für Gleitkomma anders oder ein Problem vom BCC?
-
Maxi schrieb:
audacia schrieb:
Soweit ich weiß, ist das tatsächlich undefiniert.
double foo (void) { return 0.0; } int main (void) { foo (); }Was?
Ich kann mir nicht vorstellen, dass das undefiniert sein soll.Ist es auch nicht. Mein Satz bezog sich, wie im Kontext offensichtlich wird, auf dein Codebeispiel, nicht auf mein erst nachfolgend erwähntes, und die beiden unterscheiden sich ein wenig - du gibst nämlich keinen Wert zurück

Einen Rückgabewert zu verwerfen ist natürlich legitim.
-
und wieso gibt er da ne warning und keinen fehler aus? gibts denn irgendwelche anwendungsbsp. (zumindest theoretische), in denen man das ausnutzen kann?
msvc bringt hier brav ne fehlermeldung:
error C4716: 'foo' : must return a valueallerdings nutzt er den fpu-stack auch nicht, so erhalte ich mit
return 0.;dann folgendes:
(release-mode, debug-mode war zu viel müll dabei, als das es noch übersichtlich wäre ^^)__declspec(noinline) double foo() ;nur, damit er die fkt nicht inline macht und man gar nichts mehr sieht ;D { return 0.; 00C51000 fldz ; load floating point value zero }bzw.
__declspec(noinline) double foo() { return 1.23; 00AF1000 fld qword ptr [__real@3ff3ae147ae147ae (0AF2108h)] ; load floating point value }zu fld/fldz konnte ich aber nicht wirklich was finden - scheint nur irgend nen floatingpoint-wert zu laden, aber iwie hab ich nicht so richtig die ahnung, wo das dann abgelegt werden sollte oO
hat vll jmd nen link um mein (sehr) begrenztes asm-wissen zu erweitern? ^^bb
-
audacia schrieb:
unskilled schrieb:
ist nen sicheres zeichen, den compiler zu wechseln, wenn du bei so was nich ma ne warnung erhältst
Das ist vielmehr ein Indiz, daß du mal auf Warnungen achten solltest. C++Builder emittiert in diesem Fall nicht zu Unrecht W8070.
Ja, da hast Du recht (so hab ich es dann ja schließlich auch gefunden. Hatte halt noch diverse Testvariablen drin von früheren Debuggings, wo lauter Warnungen kamen, daß Variable xy nicht verwendet wird. Da ist das untergegangen. Hab den Code jetzt ein bißchen aufgeräumt, aber kann das nur step-by-step machen)
Trotzdem, ein bißchen mehr Fehlermeldungen wären mir ja schon ganz lieb... Da tut man sich einfacher, wenn man nicht der Crack ist. Aber es ist, wie's ist...
-
susie schrieb:
audacia schrieb:
unskilled schrieb:
ist nen sicheres zeichen, den compiler zu wechseln, wenn du bei so was nich ma ne warnung erhältst
Das ist vielmehr ein Indiz, daß du mal auf Warnungen achten solltest. C++Builder emittiert in diesem Fall nicht zu Unrecht W8070.
[...]
Trotzdem, ein bißchen mehr Fehlermeldungen wären mir ja schon ganz lieb... Da tut man sich einfacher, wenn man nicht der Crack ist. Aber es ist, wie's ist...aber trotzdem sollte man sich von anfang an dran gewöhnen, warnungen zu beachten.
auch sollte man niemals fkt ohne nen return-wert implementieren - selbst am anfang, wenn man nur mal grob ne skizze machen möchte - dann tut man das halt so:double foo() { assert(0); //TODO return 0.; }- man kann nach TODO suchen
- beim testen bekommt man sofort eine fehlermeldung mit zeile etc und sieht sofort wieder, dass man dort noch was machen wollte...
wenn man will, kann man so gar noch einthrow 0;oder so nach dem assert reinmachen, damit es auch im release-mode nicht zu bösen überraschungen und zur ewigen fehlersuche kommt, weil man nicht weiß, wieso er jz unerwartet reagiert...bb
-
aber trotzdem sollte man sich von anfang an dran gewöhnen, warnungen zu beachten.
Ja, das hab ich vor.
auch sollte man niemals fkt ohne nen return-wert implementieren
Warum das? Ich hab recht viele Funktionen ohne return-Wert. Warum sollte ich die Funktion mit return-Wert machen, wenn klar ist, daß ich gar keinen brauche? Das macht es dann ja nur wieder schwerer, das Programm zu verstehen (also, was es macht).
Daß mir der Fehler passiert ist, war, weil ich die Funktion von der get-Methode kopiert habe und das vergessen habe zu ändern.
-
war etwas unglücklich ausgedrückt : D
war natürlich so gemeint:
wenn die fkt etwas zurückgeben soll und du nur noch nicht den wert bzw die rechnung dazu hast, wie das zu errechnen ist, dann solltest du erst mal irgendetwas returnen lassen usw... sry ^^bb
-
unskilled schrieb:
und wieso gibt er da ne warning und keinen fehler aus?
Keine Ahnung. Standardkonform ist es trotzdem - der Standard verlangt lediglich "diagnostics", ob diese den Buildvorgang unterbrechen müssen, ist nicht spezifiziert. Außerdem beschränkt sich der Standard hier, wenn ich mich recht erinnere, ohnehin darauf, das Ergebnis als "undefiniert" zu betrachten.
unskilled schrieb:
allerdings nutzt er den fpu-stack auch nicht
Freilich tut er - ich sehe da genau dasselbe FLD wie in meinem Code oben.
unskilled schrieb:
hat vll jmd nen link um mein (sehr) begrenztes asm-wissen zu erweitern? ^^
http://www.google.de/search?q=fstp+fld
susie schrieb:
audacia schrieb:
Das ist vielmehr ein Indiz, daß du mal auf Warnungen achten solltest. C++Builder emittiert in diesem Fall nicht zu Unrecht W8070.
Ja, da hast Du recht (so hab ich es dann ja schließlich auch gefunden. Hatte halt noch diverse Testvariablen drin von früheren Debuggings, wo lauter Warnungen kamen, daß Variable xy nicht verwendet wird. Da ist das untergegangen. Hab den Code jetzt ein bißchen aufgeräumt, aber kann das nur step-by-step machen)
Trotzdem, ein bißchen mehr Fehlermeldungen wären mir ja schon ganz lieb... Da tut man sich einfacher, wenn man nicht der Crack ist. Aber es ist, wie's ist...Du kannst das ändern - es gibt die Option, Warnungen als Fehler zu behandeln (Kommandozeilenoption
-w!). Die meisten der Warnungen von BCC sind berechtigt, daher ist der Einsatz von-w!empfehlenswert zur Förderung der Disziplin. Warnungen wie "xy wird deklariert/zugewiesen, aber nicht verwendet" (W8004/aus, W8057/par, W8080/use) kannst du deaktivieren (#pragma warn -8057oder#pragma warn -parbzw. Kommandozeilenoption-w-par).
-
hmm... stimmt^^
ty
