[Kein weiteres Interesse] lokale Variable: static vs. static const



  • DocShoe schrieb:

    Hi,

    habe hier gerade ein seltsames Problem, vielleicht kann mir ja jemand weiterhelfen.

    void Form::update()
    {
       static const time_t Offset = DateTimeToUnix( TDateTime::CurrentDateTime() ) - DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) );
    }
    

    Diese Funktion kehrt nach dem zweiten Aufruf nicht mehr zurück und die Anwendung bleibt stehen. Wenn ich jedoch das const entferne treten keine Probleme mehr auf. Ist das durch den Standard so gewollt (bzw. UB), oder ist das eine Compiler Macke?

    So wie es aussieht hast du entweder nicht den echten Code gepostet, oder das Abstürzen hat nix mit der Methode zu tun sondern ist ein Sideeffect (vllt. von DateTimeUnix oder so). Eine statische Variable (dazu const) wird einmal initialisiert. Das wars dann.



  • Einfach mit dem Debugger durchgegangen. Nach Verlassen des Funktionsrumpfes scheppert´s im Destruktor eines AnsiStrings. Der wurde temporär für den Aufruf parse_date_time_string( const AnsiString& DateTime ) erzeugt.



  • Hacker schrieb:

    So wie es aussieht hast du entweder nicht den echten Code gepostet, oder das Abstürzen hat nix mit der Methode zu tun sondern ist ein Sideeffect (vllt. von DateTimeUnix oder so). Eine statische Variable (dazu const) wird einmal initialisiert. Das wars dann.

    Bin jetzt lang genug dabei, um solche Sachen auszuschließen. Der Code ist minimal und reproduziert den Fehler zu 100%.



  • DocShoe schrieb:

    scheppert´s im Destruktor eines AnsiStrings.

    Was scheppert? Speicherfreigabe? Du siehst doch die Anweisung, nehme ich an?
    Kannst du andere Strings normal benutzen?
    Beim zweiten Funktionsaufruf passiert rein gar nichts.



  • Na hast du vermutlich Bug in parse_date_time_string() und/oder der AnsiString Klasse.



  • Ich vermute mal dein Problem liegt in parse_date_time_string(). Vermutlich schreibst du dort über Arraygrenzen? Das erklärt wieso es im Destruktor des AnsiString scheppert (der Debug Heap merkt beim delete[] dass was kaputtgegangen ist). Und es erklärt auch wieso es mit dem Stringliteral undefiniertes Verhalten liefert...



  • DocShoe schrieb:

    Der Code ist minimal und reproduziert den Fehler zu 100%.

    Der Code ist weniger als minimal. Ich krieg da

    prog.cpp:1: error: ‘Form’ has not been declared
    prog.cpp: In function ‘void update()’:
    prog.cpp:3: error: ‘time_t’ does not name a type
    

    Also Pustekuchen mit Fehler reproduzieren.

    Liefer uns den vollständigen Code, dann können wir uns mit befassen. Siehe zweiter Link in meiner Signatur unten.



  • Nein, AnsiString und parse_date_time funktionieren. Hab´ allerdings noch einmal ein paar Zeilen Code hin- und hergeschoben:

    time_t func()
    {
       return DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) );
    }
    
    void Form::update()
    {
       static time_t t1 = DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) ); // geht
       static const time_t t2 = DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) ); // geht nicht
       static time_t t3 = func(); // geht
       static const time_t t4 = func(); // geht
    }
    

    Der Bug ist zwar gefixt, aber mich interessiert trotzdem, warum Variante 2 nicht funktioniert. Wenn AnsiString oder parse_date_time buggy wären dürften alle anderen Varianten auch nicht funktionieren (gut, bei UB schwer festzustellen), aber t1 - t4 sind identisch und weisen auf korrekte Funktionsweise hin. Ich hake das als RAD Studio Macke ab, den Fix habe ich ja.


  • Mod

    Ach komm, mit über 1500 Beiträgen solltest du doch mal so langsam mitbekommen haben, dass wir den Fehler nachvollziehen können müssen, wenn wir dir bei solchen Problemen helfen sollen. Also vollständiges Minimalbeispiel, keine Behauptungen über die angebliche Fehlerfreiheit des restlichen Codes, besonders nicht, wenn man geheimnisvolle Fehler hat. pumuckl hat gestern dazu so einen schönen Beitrag geschrieben, du findest ihn als dritten Link in meiner Signatur.



  • SeppJ schrieb:

    Ach komm, mit über 1500 Beiträgen solltest du doch mal so langsam mitbekommen haben, dass wir den Fehler nachvollziehen können müssen, wenn wir dir bei solchen Problemen helfen sollen. Also vollständiges Minimalbeispiel, keine Behauptungen über die angebliche Fehlerfreiheit des restlichen Codes, besonders nicht, wenn man geheimnisvolle Fehler hat. pumuckl hat gestern dazu so einen schönen Beitrag geschrieben, du findest ihn als dritten Link in meiner Signatur.

    Aber sein Code ist doch Plattformabhängig? Dann bringt das sowieso nichts wenn 60% der User hier einen Windows-Pc oder einen Mac haben 😃



  • DocShoe schrieb:

    time_t func()
    {
       return DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) );
    }
    
    void Form::update()
    {
       static time_t t1 = DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) ); // geht
       static const time_t t2 = DateTimeToUnix( parse_date_time_string( "2012-05-29 11:00:00" ) ); // geht nicht
       static time_t t3 = func(); // geht
       static const time_t t4 = func(); // geht
    }
    

    Nach Adam Riese liegt der Fehler in DateTimeToUnix oder parse_date_time_string.

    Das sollte eigentlich offensichtlich sein... Irgendwo entsteht UB.

    @Hacker:
    Ja, n bisschen Grips ist notwendig um ein Minimalbeispiel zu bauen dass funktioniert. String Klassen kann man idR ohne Probleme durch std::string ersetzen und Form ist unnötig. Puh, das kostet mich vielleicht 40 Sekunden arbeit. Oh Mein Gott.



  • Schepperts hier auch?

    static const XYZ t2 = parse_date_time_string( "2012-05-29 11:00:00" );
    


  • Edit: Doppelpost



  • Shade Of Mine schrieb:

    @Hacker:
    Ja, n bisschen Grips ist notwendig um ein Minimalbeispiel zu bauen dass funktioniert. String Klassen kann man idR ohne Probleme durch std::string ersetzen und Form ist unnötig. Puh, das kostet mich vielleicht 40 Sekunden arbeit. Oh Mein Gott.

    Jau. Und das kann den Fehler aber auch schon lösen 😉 denn vielleicht ist er ja gerade dann in den Plattformabhängigen Libs versteckt.



  • Hacker schrieb:

    Jau. Und das kann den Fehler aber auch schon lösen 😉 denn vielleicht ist er ja gerade dann in den Plattformabhängigen Libs versteckt.

    Dann haben wir den Fehler gefunden und das Problem gelöst. Perfekto.


Anmelden zum Antworten