shr -> Teilbar durch 64 wird ingnoriert.

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Mathias »

Alle shr-Werte, welche durch 64 teilbar sind, werden ignoriert. Getestet mit Linux 64Bit.

Code: Alles auswählen

var
  i: PtrUInt = 1;
begin
  WriteLn(i);            // 1
  WriteLn(i shr 32);     // 0
  WriteLn(i shr 64);     // 1
  WriteLn(i shr 128);    // 1
  WriteLn(i shr 192);    // 1
  WriteLn(i shr 256);    // 1
  WriteLn(i shr 512);    // 1
  WriteLn(i shr 100);    // 0
  WriteLn(i shr 333);    // 0
end.     
Auch wen ich i auf den maximalen Wert setze " i := MaxUIntValue" das selbe in grün, alles teilbar mit 64 wird ignoriert, alles andere geht.,
Was dabei auch noch komisch ist, shr 364 und 300 geben das gleiche Resultat, aber dies könnte daran liegen, das ein die vorderen Bits abgeschnitten werden, aber nach meiner Meinung, müsste da "0" kommen, wen mal alles vom Stapel runtergerutscht ist.

Mit shl, ist das ganze Verhalten Ähnlich.

Ist dies ein Bug, oder ist dies so gewollt ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Joh
Lazarusforum e. V.
Beiträge: 176
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Joh »

ähem,
shr 64 shiftet 64x nach rechts, also 64 bit... da sollte dein 32bit PointerUInt schon lange zuende sein?!

Wahrscheinlich meinst du
shr 6 => durch 64 teilen?
just my two Beer

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Mathias »

ähem,
shr 64 shiftet 64x nach rechts, also 64 bit... da sollte dein 32bit PointerUInt schon lange zuende sein?!
Ein Pointer ist bei einer 64Bit Plattform 64Bit und nicht 32Bit.
Wahrscheinlich meinst du
shr 6 => durch 64 teilen?
Nein, ich meinte schon Shiften und nicht teilen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von theo »


Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Mathias »

Anscheinend eine ominöse Sache, mit der man leben muss.
Ich bin heute per Zufall auf dieses Problem gestossen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 24. Mai 2023, 13:44
Ist dies ein Bug, oder ist dies so gewollt ?
Das ist einfach „undefined behavior”. Für einen 64-Bit Wert ist shr (und shl) nur für den Bereich 0 bis 63 definiert (bei einem 32-Bit Wert entsprechend 0 bis 31), alles andere ist nicht definiert und der Compiler kann daher machen was er will und es ist richtig (im konkreten Fall macht der Compiler einfach ein Modulus mit der Bitbreite auf den Shiftwert).
FPC Compiler Entwickler

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Socke »

PascalDragon hat geschrieben:
Mi 24. Mai 2023, 22:45
Das ist einfach „undefined behavior”. Für einen 64-Bit Wert ist shr (und shl) nur für den Bereich 0 bis 63 definiert (bei einem 32-Bit Wert entsprechend 0 bis 31), alles andere ist nicht definiert und der Compiler kann daher machen was er will und es ist richtig
Wäre es dann nicht im Sinne einer sicheren Sprachverwendung zumindest eine Warnmeldung zu erzeugen? Persönlich fände ich eine Fehlermeldung schöner, bei einer Warnmeldung ist man aber voll abwärtskompatibel. Auf der anderen Seite ist eine Fehlermeldung in Version 3.3.x in dem undefinierten Verhalten in Version 3.2.x enthalten - als ein mögliches, aber nicht implementiertes Verhalten.

Wird die Anzahl der zu verschiebenen Bits erst zur Laufzeit mitgegeben, könnte ein Laufzeitfehler im Range Checking ausgelöst werden.

In jedem Fall besteht aber ein Bug in der Dokumentation. Dort ist weder der gütlige Wertebereich angegeben noch wird auf das undefinierte Verhalten hingewiesen.

Was undefiniertes Verhalten alles bewirken kann, wird in dieser Präsentation ganz gut zusammengefasst.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Joh
Lazarusforum e. V.
Beiträge: 176
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: shr -> Teilbar durch 64 wird ingnoriert.

Beitrag von Joh »

Da shr und shl eigentlich eine 1:1-Übersetzung des Assemblerbefehls ist, sollte man erstmal auf Prozessorebene schauen, was dann eigentlich passiert.

Meine (nie wirklich großen) Assemblerkenntnisse sind mittlerweile eingerostet.
Aber zur Theorie:
man packt einen Wert in ein Register und verschiebt diesen Wert um shr(x) Bytes nach rechts.
Was soll daran Sinn ergeben, diesen Wert über mehr Stellen zu shiften, als das Register breit ist?
Wie ist dieses Vorgehen lt. x86-Spezifikation spezifiziert?

Aber grundsätzlich sollte man davon ausgehen, das shr/shl nur bis Registerbreite-1 sinnvoll ist.

Ob jetzt konkret der Ryzen5 schlagmichtot den Wert mod Registerbreite durchführt oder ein anderes Register zur Hilfe nimmt ist letztlich irrelevant.
just my two Beer

Antworten