Bug in C++ Builder 5 - Ungültige Gleitkommaoperation?



  • Hallo

    Naja für uns hier ist es natürlich nicht komplett ausschließbar, das dein Arbeitspeicher einen Hardwarefehler hat. Der würde sich aber kaum so gezielt äußern, da müßten nach hinreichend langer Zeit auch mal andere Programme davopn betroffen sein.

    Das der Fehler in deinem Code ist halte ich für wesentlich wahrscheinlicher.

    bis bald
    akari



  • jf_stgt schrieb:

    Ich bin auch kein Freund von globalen Variablen aber manchmal sind diese einfach sehr geschickt.

    Ich wüsste keinen Fall in denen ich eine globale Variable als "geschickt" bezeichnen könnte. Selbst in dem Fall das ich Tatsächlich mal Daten global haben müsste (ich erinnere mich nicht es in der Vergangenheit mal wirklich gebraucht zu haben), gibt es eine bessere Alternative (mit klarer Definition des Initialisierungszeitpunktes):

    int& GlobalerWert()
    {
        static int = 0;
        return int;
    }
    

    Aber selbst das Konstrukt habe ich bislang kaum verwendet.

    cu André



  • akari schrieb:

    Naja für uns hier ist es natürlich nicht komplett ausschließbar, das dein Arbeitspeicher einen Hardwarefehler hat. Der würde sich aber kaum so gezielt äußern, da müßten nach hinreichend langer Zeit auch mal andere Programme davopn betroffen sein.

    Ne, an einen Hardwarefehler glaube ich auch keinesfalls.

    Eher, dass irgendein Array über seine Grenzen gefüllt wird oder (und um das ging es mir hier), dass Borland hier irgendwas irgendwo hinschreibt. Oder ist dies unwahrscheinlich?
    Wenn es ein Programmierfehler von mir ist und wirklich hier Grenzen überschrieben werden - wie solle ich den finden?



  • Hallo

    Es ist natürlich auch möglich das irgendein anderer deiner Speicherzugriffe (wie du schon selbst sagst Array oder Pointer sinf potentielle Kandidaten) fälschicherweise den Speicher überschreibt. Das könnte aber dann nur zwischen dem letzten Schreibzugriff und dem fehlerauslösenden Lesezugriff auf FAKTORX passieren. Vielleicht hilft dir ja diese Einschränkung.

    Aber auch hier halte ich es sehr viel wahrscheinlicher das die Ursache in deinem Code liegt als im Code von der VCL, im Borland-Compiler oder gar in der Speicherverwaltung von Windows.

    bis bald
    akari



  • Könnte Dir eigentlich ein Watchpoint helfen? Das er anhält wenn der Speicher überschrieben wird? Ich arbeite leider zu selten mit dieser Technik...



  • witte schrieb:

    Könnte Dir eigentlich ein Watchpoint helfen? Das er anhält wenn der Speicher überschrieben wird? Ich arbeite leider zu selten mit dieser Technik...

    Ich weiß gar nicht ob das mit dem C++ Builder überhaupt geht???! Ich habe auf Anhieb leider nichts gefunden.

    Was witziges was schon auf so einen Speicherfehler hindeutet:

    int abc = 12 * FAKTORX; // (1)
    int def = 9 * FAKTORX; // (2)
    

    In Zeile 1 steht laut Breakpoint FAKTORX auf 0 und die Zeile läuft auch.
    In Zeile 2 steht laut Breakpoint FAKTORX immer noch auf 0 (klar!) aber wenn ich F8/F7 drücke, knallt es mit bekannter Fehlermeldung.



  • Ich kanns mir zwar net erklären, aber ich habe das

    float FAKTORX
    

    in ein

    int FAKTORX
    

    umbenannt und in meinem Code ein Faktor 100 miteingerechnet (damit ich auf die Genauigkeit komme die ich brauche) und nun geht es.



  • jf_stgt schrieb:

    Ich weiß gar nicht ob das mit dem C++ Builder überhaupt geht???!

    Natürlich geht das, nur heißt das da "Datenhaltepunkt".



  • audacia schrieb:

    jf_stgt schrieb:

    Ich weiß gar nicht ob das mit dem C++ Builder überhaupt geht???!

    Natürlich geht das, nur heißt das da "Datenhaltepunkt".

    Aha. Klingt gut. Und wo finde ich den?



  • Start|Haltepunkt hinzufügen...|Datenhaltepunkt?



  • Hallo zusammen,

    also es ist echt zum verzweifeln.
    Ich habe so langsam alles versucht.
    Die globalen Variablen habe ich alle zu Klassenvariablen meiner Hauptform gemacht und sie in den anderen Formen mit hauptform->variable angesprochen.
    Auch der Datenhaltepunkt hat nichts gebracht.

    Das Problem tritt immer noch auf!
    Es hängt aber mit double oder float Variablen zusammen und es ist nicht immer FAKTORX. Manchmal läuft er nach dem Compilieren am "FaktorX Problem vorbei" und bringt den Fehler in einer ganz anderen Form.
    *.ob, *.tds und sonstige Dateien habe ich auch weggelöscht.

    Wie gesagt, das sonderbare ist, dass es nach dem kompletten Rebuild geht, aber wenn ich dann nur eine Unterform ändere und mit F9 kompiliere, steigt er mir aus.

    Habt ihr noch ein Tipp?

    Viele Grüße
    jf_stgt



  • Du könntest versuchen ein Minimalprojekt zu erstellen, bei dem der Fehler reproduzierbar ist. Dabei würdest Du die Abhängigkeiten dieses Fehlers sehen. Dann könntest Du ihn evtl. hier posten.



  • Wie schon erwähnt wird es wohl irgendwo in deinem Code zu undefinierten Verhalten kommen der sich dann später als Fehler ausdrückt. Versuche mal einfach alles mögliche auszukommentieren, bis der Fehler nicht mehr auftritt. Dann füge nach und nach wieder das auskommentierte ein. Dann wirst du schon sehen woran es wirklich liegt.



  • witte schrieb:

    Du könntest versuchen ein Minimalprojekt zu erstellen, bei dem der Fehler reproduzierbar ist. Dabei würdest Du die Abhängigkeiten dieses Fehlers sehen. Dann könntest Du ihn evtl. hier posten.

    Dies ist etwas schwierig, da ich wirklich viele Formulare habe und da nicht einfach Formulare rauslösen kann da die ja zum Teil aufeinander aufbauen.
    Aber ich werde es versuchen.

    Braunstein schrieb:

    Wie schon erwähnt wird es wohl irgendwo in deinem Code zu undefinierten Verhalten kommen der sich dann später als Fehler ausdrückt. Versuche mal einfach alles mögliche auszukommentieren, bis der Fehler nicht mehr auftritt. Dann füge nach und nach wieder das auskommentierte ein. Dann wirst du schon sehen woran es wirklich liegt.

    Das mit dem Auskommentieren ist eine gute Idee (könnte von mir sein). Ich werde mal alles auskommentieren was ich in den letzten 1-2 Wochen geändert habe.
    Das dumme ist, das der Fehler nicht immer auftritt.
    aber man könnte natürlich warten, bis der Fehler kommt - dann auskommentieren. Form für Form. Und wenn er weg ist, ists klar woher es kommt, oder?

    Eine maximale Größe einer (verabeitbaren) Header/C++ Datei gibt es nicht, oder? Ich habe nämlich v.a. in einer Form viele neue Labels eingefügt. Die sind dann ja im Header und dieser Header wird dann im Hauptform eingebunden (incude).

    Gruß
    jf_stgt



  • Brobier es doch mal mit Units einbinden oder du
    schreibst oben unter (oder über)

    #include "Unit2.h"
    #include "Unit3.h"
    ...
    //oder wie der name der Unit ist
    

    Dann compilirt er (PC) den ganzen Code 👍 IMMER 👍 beim ausführen des prog. 😉



  • [NOVA] Max schrieb:

    Brobier es doch mal mit Units einbinden oder du
    schreibst oben unter (oder über)

    #include "Unit2.h"
    #include "Unit3.h"
    ...
    //oder wie der name der Unit ist
    

    Dann compilirt er (PC) den ganzen Code 👍 IMMER 👍 beim ausführen des prog. 😉

    Tut mir leid, so ganz verstehe ich Deinen Beitrag nicht.
    Was meinst Du mit, "oben unter (oder über)" ?

    So langsam habe ich es echt satt. Habe nun mehrere Tage auskommentiert, alte Dateien hin un her kopiert. Irgendwann tritt der Fehler dann mal auf, dann versuche ich meine Änderungen wieder rückgängig zu machen - irgendwann ist der Fehler dann wieder weg, ... 😮 😮 😮

    Ich kann nicht mal genau sagen ab wann der Fehler auftaucht. So eine Sch.. aber auch.

    Hat noch jemand einen schlauen Tipp!

    Was mich noch interessieren würde in diesem Zusammenhang. Wie groß sind eure größten c++ / obj Files (kByte) bei großen Projekten? Vielleicht hängt es ja doch irgendwie mit der Größe zusammen?



  • jf_stgt schrieb:

    So langsam habe ich es echt satt. Habe nun mehrere Tage auskommentiert, alte Dateien hin un her kopiert. Irgendwann tritt der Fehler dann mal auf, dann versuche ich meine Änderungen wieder rückgängig zu machen - irgendwann ist der Fehler dann wieder weg, ... 😮 😮 😮

    Wenn sich deine Minimalversion des Projekts dem Zustand nähert, da du es hier veröffentlichen kannst, könnten wir dir besser bei der Fehlersuche helfen.

    Hast du mal versucht, vorcompilierte Header zu deaktivieren, nur um das als Fehlerursache auszuschließen?

    jf_stgt schrieb:

    Auch der Datenhaltepunkt hat nichts gebracht.

    Was soll das heißen? Funktioniert er nicht, wird also der Wert verändert, ohne daß der Haltepunkt aktiviert würde?



  • audacia schrieb:

    Wenn sich deine Minimalversion des Projekts dem Zustand nähert, da du es hier veröffentlichen kannst, könnten wir dir besser bei der Fehlersuche helfen.

    An sich verstehe ich das. Aber das Projekt ist immer noch sehr umfangreich und ich darf den Quelltext hier auch nicht veröffentlichen (Geheimhaltung).

    audacia schrieb:

    Hast du mal versucht, vorcompilierte Header zu deaktivieren, nur um das als Fehlerursache auszuschließen?

    Nein. Ich hatte die vorcomp. Header mal ausgeschaltet, dann compiliert er aber alles neu (klar). Danach war der Fehler weg. Aber nach dem kompletten Recompile ist der Fehler immer weg. Ich hatte dann die vorc. Header wieder eingeschaltet um die Compile-Zeit geringer zu halten. Aber ich werde auch in diese Richtung noch einmal forschen.

    Datenhaltepunkt:

    audacia schrieb:

    Was soll das heißen? Funktioniert er nicht, wird also der Wert verändert, ohne daß der Haltepunkt aktiviert würde?

    Er funktioniert schon. Das Programm bleibt (an der richtigen - beabsichtigten Stelle) stehen und an sonst keiner Stelle. Der Wert wird also nicht verändert!

    Dazu noch eine Begebenheit.

    verh = laenge * (int)(FAKTORX / 100.0);
    

    FAKTORX ist ja ein globaler double Wert. Und hier kommt ja der Fehler. Zwei Zeilen davor ist eine ähnliche Berechnung:

    erg = breite * (int)(FAKTORX / 100.0);
    

    Da läuft er über FAKTORX drüber ohne Probleme (obwohl der Debugger auch schon 0,000000xx) als Wert anzeigt! Da müsste es ja dann auch "knallen".

    Wenn ich die zweite (defekte) Zeile umbaue zu:

    double faktorlokal = FAKTORX; // (1)
    verh = laenge * (int)(faktorlokal / 100.0);
    

    stirbt er in der mit (1) gezeichneten Stelle.

    Dubios, oder? Ist ja nur eine Zuweisung.



  • Du könntest beim Debuggen in die Assembler-Ebene gehen ("CPU-Fenster") und schauen wie er das kompiliert hat und wie die Register sich ändern.



  • witte schrieb:

    Du könntest beim Debuggen in die Assembler-Ebene gehen ("CPU-Fenster") und schauen wie er das kompiliert hat und wie die Register sich ändern.

    Das habe ich auch schon gemacht. Aber ehrlich gesagt verstehe ich den Assembler Code da nicht so ganz.

    Noch was "witziges".
    Mein Fehler tritt ja irgendwann mal bei einer Änderung in einer Form (Form2) auf. Form2 wird also verändert. Dann knallt es in Form1 obwohl da gar nichts verändert ist. Es hat irgendwas mit den double Variablen zu tun. Die sind ab da irgendwie kaputt.
    Klingt seltsam, ich weiß, aber wenn ich z.B. in meine Projektdatei.cpp (also die mit CreateForm, ...) ganz oben nach den Headern einfüge:

    double mwst = 19.0; // Zeile 1
    double mwstSatz = mwst / 100; // Zeile 2
    double mwstSatzKplt = 1 + mwstSatz; // Zeile 3
    

    dann läuft alles nach einem Komplett-Kompilieren normal.
    mwstSatz ist 0,19
    mwstSatzKplt ist 1,19.

    Nach einer kleinen Programmänderung in Form2 ist
    mwstSatz ist 0,000000012 * 10^-234 (also quasi Null)
    Zeile 3 reagiert mit einer Schutzverletzung (Ungültige Gleitkommaoperation).
    Obwohl ich in Projektdatei.cpp nichts verändert habe und dies auch aufgerufen wird bevor irgendwelche sonstigen Formulare erzeugt werden.

    Was meint ihr?


Anmelden zum Antworten