Oder man schreibt halt gleich alles in Assembler.
...also, ich hatte doch neulich diese lustige Sache, wo floor() plötzlich immer 1 zurückgegeben hat. Heute ist das wieder aufgetreten und ich bin dem mal ein bisschen hinterhergestiegen. Also so richtig gefällt mir das nicht, was gcc da macht.
Also, ich hab es reproduziert und angehängt.
Es gibt eine Datei parameter.h, da stehen alle möglichen Variablen drin. Alle const int oder const double. Nun sind da zwei Zeilen vertauscht, so dass eine Variable "defined_late" in der Zuweisung einer anderen benutzt und danach erst definiert wird.
Der Compiler beschwert sich nicht, weil die Variablen beide schon bekannt sind - es gibt nämlich noch die Datei "also_included.cpp", in der defined_late benutzt wird. Ich finde trotzdem, er sollte wenigstens eine Warnung werfen. Selbst mit -Wall kriege ich nix.
Einerseits wird jetzt 0 zugewiesen, okay, damit könnte man vielleicht leben. Uninitialisierter Trash halt. Aber, der Witz ist, ab jetzt funktionieren floor() und ceil() nicht mehr!
Zum Reproduzieren:
Code:g++ main.cpp -O0 -g gdb a.out break main.cpp:24 run print floor(25.7)
/edit das entscheidende "run" nachgetragen
Geändert von Gullix (23. Februar 2015 um 21:18 Uhr)
Mit Naturgesetzen kann man nicht verhandeln. --Harald Lesch
Ein Atomkrieg würde die Menschheit auslöschen. Hätte aber auch Nachteile.
...also, ja schon. Genau genommen der uninitialisierte Wert von defined_late. Spannend fände ich eher, ob dein Debugger noch vernünftiges floor() bzw ceil() kann, nachdem er das geladen hat. Bei mir am Arbeitsrechner (Ubuntu) gings nicht.
Mit Naturgesetzen kann man nicht verhandeln. --Harald Lesch
Ein Atomkrieg würde die Menschheit auslöschen. Hätte aber auch Nachteile.
Wenn ich das richtig gemacht habe, kommt bei "print floor(25.7)" 6015 heraus.
(Wusste gar nicht, dass gcc einen interakiven Debugger hat. )
...also, wow, 6015 ist ja mal weit weg von allem, was Sinn machen würde.
Mit Naturgesetzen kann man nicht verhandeln. --Harald Lesch
Ein Atomkrieg würde die Menschheit auslöschen. Hätte aber auch Nachteile.
Mal nee Frage: Kennt sich jemand mit Prolog aus? Ist auch nee relativ einfache Frage:
Und zwar wenn ich das semicolon als OR Operator verwende und zbs sowas wie true;false;true;true;false. als Querry frage, dann gibt er nicht nur eine Lösung aus, sondern 3 mal true und ein abschließendes False.
Was geschieht da? Warum wird nicht nur ein einziges True ausgegeben, sondern die einzelnen Trues einzeln nacheinander abgearbeit und die Teile ausgegeben?
Für das Resultat musst du in Prolog etwas anderes eingeben als du hier beschreibst.
Zugriff auf ne uninitialisierte Variable ist nicht nur ein beliebiger Wert, sondern undefiniertes Verhalten. Ein bischen Erklaerung dazu gibt es hier: http://stackoverflow.com/a/11965368/620382 . Undefiniertes Verhalten bedeutet halt auch, dass sowas wie mit floor/ceil passieren kann. Debugger funktionieren ja generell nicht immer so wie man sich das vorstellt.
Das schlimme an dem Beispiel ist, dass weder g++ noch clang++ hier mit -Wall -pedantic meckern. Dabei liest sich das fuer mich ziemlich eindeutig problematisch. Nicht unbedingt die Reihenfolge, aber auch das du hier einem extern const in der selben compilation unit noch einen Wert zuweist - bin mir nicht sicher ob das Sinn ergibt.
Achtung Spoiler:
Ich wollte sagen, dass deine Beschreibung hier nicht mit dem übereinstimmt, was du eingegeben hast. (Oder sich deine Prolog-Implementierung von gprolog (Standard unter Ubuntu, was ich zum Testen installiert habe) unterscheidet).
Wenn ich „true;false;true;true;false.“ eingebe gibt er einmal true aus und wenn man Enter betätigt 'yes'. Also musst du was eingegeben haben, was du uns nicht mitgeteilt hast. Grundsätzlich versucht Prolog alle Lösungen auszugeben, die es findet. (Sofern man nicht nach dem ersten abbricht.)