Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Conpiler macht Mist: For schleife mit Falschen werten
Flamefire - Fr 31.07.09 16:47
Titel: Conpiler macht Mist: For schleife mit Falschen werten
Hi,
hab mal wieder feststellen müssen, dass mein Compiler (D2009) Mist macht.
Hab folgende Function:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| class procedure Tfoo.bar(var stream:byte8;key1:Cardinal;key2:Byte); var i:Integer; key1a:Array[0..3] of Byte; begin PCardinal(@key1a[0])^:=key1; for i:=0 to 3 do stream[i]:=stream[i] XOR (stream[i]+key1a[i]+key2); for i:=4 to 7 do stream[i]:=stream[i] XOR (stream[i]+key1a[i-4]+key2); end; |
und was macht mir der Compiler aus der ersten Schleife von 0 bis 3?
Ein schleife von 4 bis 1!!! (Habs im ASM angeguckt)
Folge: RangeCheck Error!
Warum bitte das?
Wie kann ich das vermeiden?
EDIT: type byte8=array[0..7] of Byte; fehlte
Marc. - Fr 31.07.09 16:58
Ich hab's grad ausprobiert. Das liegt an der Optimierung vom Compiler. Wenn Du diese via {$O-} ausschaltest, klappt's einwandfrei. ;)
Warum der Compiler allerdings durch die Optimierung solch ein Fehlverhalten zeigt, ist mir ein Rätsel. :nixweiss:
Flamefire - Fr 31.07.09 17:05
its ja mal ganz toll...wenn man sich nicht auf den compiler verlassen kann...
Muck - Fr 31.07.09 17:22
Hallo,
ich habe die Funktion in Delphi 2009 getestet und die Function selbst mit Code optimierung funktioniert fehlerfrei.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| Unit1.pas.31: PCardinal(@key1a[0])^:=key1; 0046423C 8BDC mov ebx,esp 0046423E 8913 mov [ebx],edx Unit1.pas.32: for i:=0 to 3 do 00464240 BE04000000 mov esi,$00000004 // Schleife hat 4 Durchlaeufe 00464245 8BD0 mov edx,eax // edx ist offset zu key1a 00464247 8BFC mov edi,esp // edi ist offset zu stream Unit1.pas.33: stream[i]:=stream[i] XOR (stream[i]+key1a[i]+key2); 00464249 0FB61F movzx ebx,[edi] 0046424C 021A add bl,[edx] 0046424E 02D9 add bl,cl 00464250 301A xor [edx],bl 00464252 47 inc edi // naechstes byte fuer stream 00464253 42 inc edx // neachstes byte for key1a Unit1.pas.32: for i:=0 to 3 do 00464254 4E dec esi // esi -- 00464255 75F2 jnz $00464249 // wenn nicht null weitermachen |
das ist alles fehlerlost, kein Fehler im Compiler.
Die Optimierung berechnet die Differenz des Schleifenzaehlers (ESI 4) und nutzt andere Register fuer den Index auf Arrays. Die Variable I gibt es nicht wirklich waehrend des Schleifendurchlaufs.
Markus
Flamefire - Di 04.08.09 19:53
hm ok...dann hab ich mich vermutlich von esi irritieren lassen, und der anzeige von i=4 im debugger
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!