Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehler in Delphi mit For-Schleife (https://www.delphipraxis.net/67829-fehler-delphi-mit-schleife.html)

s.h.a.r.k 20. Apr 2006 13:57


Fehler in Delphi mit For-Schleife
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich habe da einen Fehler in Delphi und weiß nicht einmal wieso! Schaut euch mal das Bild im Anhang an. Dort habe ich eine Prozedur gepostet, die Einträge in eine ListView schreibt. Laut dem Code würde das ganze ja auch funktioniert, nur jetzt stellt Delphi was "perverses" mit der For-Schleife an, was ich nicht wirklich nachvollziehen kann.

Laut For-Schleife sollte i bei 0 beginnen und bei 5 aufhören (=Länge des Array minus 1) - Nur beginnt die ganz for-Schleife bei 6 :gruebel: bin ich zu blöd, hab ich einen Fehler drin oder macht das nur mein PC so?

PS: Ich hatte das Problem schon einmal, das war aber damals bei Delphi 5. Konnte es damals nur lösen, in dem ich aus der For-Schleife eine While-Schleife machte, was ich aber nicht will. Das muss doch auch anders gehen!

mfg
shark

BenjaminH 20. Apr 2006 14:05

Re: Fehler in Delphi mit For-Schleife
 
Das hatten wir schon ein paarmal, das ist Optimierung, die der Compiler automatisch macht.
Es geht einfach schneller runterzuzählen, als rauf.

Hawkeye219 20. Apr 2006 14:09

Re: Fehler in Delphi mit For-Schleife
 
Hallo Armin,

Benjamin hat es ja schon kurz beschrieben. Die ausführliche Erklärung findest Du u.a. hier.

Gruß Hawkeye

alcaeus 20. Apr 2006 14:11

Re: Fehler in Delphi mit For-Schleife
 
Nun ja, die Optimierung ist ja eine Sache, aber die wuerde dann trotzdem nur von 5 auf 0 runterzaehlen, und nicht von 6 abwaerts ;)

Greetz
alcaeus

Klaus01 20. Apr 2006 14:12

Re: Fehler in Delphi mit For-Schleife
 
ich denke, dass das ganze wohl nichts mit der
Optimierung zu tun haben sollte.
Wenn der Compiler schon optimiert, dann kann es aber nicht sein
das die Laufvariable einen Wert annimmt der nicht sein darf.

In diesem Fall 6; i kann bzw. sollte doch nur einen Wert von 0 bis max 5 haben.
Tritt Dein Problem auch dann auf wenn Du z.B.
die Prozedure so anpasst, dass Du eine Const max definierst
und das Array NavItems : array[0..max] of array[0..1] of string ...
so definierst.

Die for-Schleife kann dann auch von 0 bis max laufen.
Wird dann immernoch falsch "optimiert"?

Mag es sein, dass length nicht mit dem 2 dimensionalem Array zurechtkommt.

Aus der Hilfe: length - Returns the number of characters in a string or elements in an array.
Und Dein Array hat 6 * 2 Elemente.

Grüße
Klaus


[edit] Text ergänzt [/edit]

alzaimar 20. Apr 2006 14:14

Re: Fehler in Delphi mit For-Schleife
 
Rückwärtszählen ist zwar grundsätzlich eine legitime Optimierungsmöglichkeit, aber hier scheint Delphi nicht nur übers Ziel hinauszuschiessen, sondern auch völig durcheinander zu kommen, oder ist das ein verspäteter Aprilscherz :gruebel: . Und wenn ja, von wem?

Um es genau zu sagen: Delphi optimiert hier den Code kaputt! Wenn s.h.a.r.k hier den verbindlichen Ablaufplan eines Hausbaus in eine Listview schreiben würde (Erst Keller, dann Boden, Wände, 1.Stock ... und zum Schluss das Dach), dann würde Delphi daraus eine ziemlich schwer zu realisierende Arbeitsabfolge generieren; Wer kann schon beim Häuslebau mit dem Dach anfangen...? :wall:

Für mich eindeutig ein Fall für Borland bzw. den Delphi-Bug-Report hier im Forum.

PS: D6E funktioniert (natürlich)

Hawkeye219 20. Apr 2006 14:20

Re: Fehler in Delphi mit For-Schleife
 
Es sind 6 Elemente, 6 mal Dekrementieren führt zum Wert 0, und den Test auf 0 kann man mit einem Assemblerbefehl durchführen.:wink:

//Edit: wenn die Laufvariable noch an anderen Stellen benutzt wird, findet keine Optimierung statt.

Gruß Hawkeye

JasonDX 20. Apr 2006 14:21

Re: Fehler in Delphi mit For-Schleife
 
Zitat:

Zitat von alcaeus
Nun ja, die Optimierung ist ja eine Sache, aber die wuerde dann trotzdem nur von 5 auf 0 runterzaehlen, und nicht von 6 abwaerts ;)

afair laeufts intern so ab:

schleifenanfang:
i := 6
//inhalt der schleife
dec(i)
wenn i <> 0 gehe zu schleifenanfang

oder anders ausgedrueckt:
Code:
mov eax, $000000006 //unser i
//schleifenanfang:
inc ebx //ich hatte ein einfaches inc(r) drinnen
dec eax
jnz -$04 //zurueck zum schleifenanfang springen
Folgendermassen muss er bei 6 anfangen und zaehlt bis 1 runter. wenn er bei 0 ankommt springt er raus.
Was das problem ist ist, dass er nicht merkt, dass die Zaehlvariable verwendet wird, denn normalerweise duerfte dann diese Optimierungsmoeglichkeit nicht mehr greifen.

[Add]
Als Problemloesung duerfte dann ein Ausschalten der Optimierung fuer diese Methode reichen, zumindest theoretisch.
[/Add]



greetz
Mike

Robert Marquardt 20. Apr 2006 14:42

Re: Fehler in Delphi mit For-Schleife
 
Du gehst von der falschen Voraussetzung aus das die Tooltips immer korrekt sind.
Das ist insbesondere bei einem Programm mit aktivierter Optimierung nicht der Fall.

Khabarakh 20. Apr 2006 14:48

Re: Fehler in Delphi mit For-Schleife
 
Tja, der Compiler ist doch etwas schlauer.
Ich kann zwar keinen Funken Assembler, aber zur Analyse dieses Codes hat es gerade noch gereicht (sofern es überhaupt stimmt ;) ):
Delphi-Quellcode:
var
  i: Integer;
const
  bla: Array[0..5] of string = ('a', 'c', 'e', 'blubb', 'blubber', 'bubbsten');
begin
  for i := 0 to 5 do
    Writeln(bla[i]);
  Readln;
end.
Auch hier beginnt i mit 6. Der Witz ist aber, dass i für den Arrayzugriff überhaupt nicht benutzt wird. Vor Schleifenbeginn wird @bla in EBX gespeichert und mit jedem Durchgang um 4 erhöht, der Compiler kann also immer noch optimieren, wie JasonDX es erklärt hat. Gleiches wird wohl bei shark passiert sein, da dort ebenfalls nur auf ein Array zugegriffen wird.

So etwas kommt eben davon, wenn man auf die Idee kommt, mit Optimierungen zu debuggen :wall: .

JasonDX 20. Apr 2006 14:53

Re: Fehler in Delphi mit For-Schleife
 
Zitat:

Zitat von Robert Marquardt
Du gehst von der falschen Voraussetzung aus das die Tooltips immer korrekt sind.
Das ist insbesondere bei einem Programm mit aktivierter Optimierung nicht der Fall.

Ich hab grad nochmal a bissl im asm-durcheinander gewuelt, und siehe da: Delphi interessiert sich nicht fuer den Inhalt von i. Die schleife koennte somit auch von 932745 bis 932739 laufen, und es wuerde nichts aendern. Ein Array hat naemlich die Angewohnheit, schoen seine Werte der Reihe nach im Speicher zu behalten. Also waers ziemlich dumm, jedesmal nach der Adresse des arrays zu fragen, um an das aktuelle Element zu gelangen. Stattdessen wird die Startadresse des Arrays genommen, bzw. das erste verwendete Element, und immer nur die Groesse des Elementes zum Zeiger dazugezaehlt. Damit zeige ich mit nur einer Addition immer aufs aktuelle Element, welche auch schoen nach der Reihe abgearbeitet werden, naemlich vom ersten bis zum letzten, und nicht umgekehrt. Wer schon mal in C mit Pointern gespielt hat, weiss was ich meine.
Es ist dann ein bisschen verwirrend, da ich im Code auf das Arrayelement mit einem Index zugreife, auf dem eigentlich nur Bockmist steht, aber es trotzdem funktioniert. Ergo: Sowohl die Tooltips stimmen, als auch die Compileroptimierung und die Reihenfolge des Zugriffs auf die Arraywerte, und der Hausbau wuerde somit immernoch beim Keller anfangen ;)

greetz
Mike

[Edit] Ich werd zu langsam, und meine Affaere mit dem Roten Kasten geht auch in die Brueche :cry:

Luckie 20. Apr 2006 15:10

Re: Fehler in Delphi mit For-Schleife
 
Gückgück: http://www.delphipraxis.net/internal...+r%FCckw%E4rts
Insbesondere die Beiträge von mir und Hagen.

alzaimar 20. Apr 2006 15:33

Re: Fehler in Delphi mit For-Schleife
 
@s.h.a.r.k und Alle mit BDS2006: Funktioniert das denn oder nicht? Das ist doch das Einzige, was zählt.

Luckie 20. Apr 2006 15:36

Re: Fehler in Delphi mit For-Schleife
 
Ich suche gerade nach einem einfachen Beispiel, einfach deshalb damit der ASM Code im CPU-Fenster übersichtlich bleibt. Leider bisher ohne Erfolg:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  IntArray: Array of Integer;
begin
  SetLength(IntArray, 10);
  for i := 0 to 9 do
    IntArray[i] := i;
end;
Wie müsste eine Schleife aussehen, die optimiert wird und somit rückwärtsläuft? Aber sie muss möglichst einfach sein. So bald man ShowMessage oder gar IntToStr aufruft, geht es im CPU-Fenster wild durch alle möglichen calls durch. :?

JasonDX 20. Apr 2006 15:49

Re: Fehler in Delphi mit For-Schleife
 
Bei mir hat das gereicht:
Delphi-Quellcode:
var
  ar: array[0..5] of integer = (0, 1, 2, 3, 4, 5);

//...
var
  i, r: integer;
begin
 r := 0;
  for i := 0 to 5 do
  begin
    inc(r, ar[i]);
  end;
  ShowMessage(IntToStr(r)); //Wird benoetigt, damit ueberhaupt was mit r gemacht wird (ansonsten wird das inc von der Optimierung weggeschnibbelt)
end;
i wird auf 6 initialisiert und bis 0 runtergezaehlt, in r steht nach der Schleife 15 drinnen. Es funktioniert also, sowohl D7, als auch DS06...

Zitat:

Zitat von Luckie
Aber sie muss möglichst einfach sein. So bald man ShowMessage oder gar IntToStr aufruft, geht es im CPU-Fenster wild durch alle möglichen calls durch. :?

Die Schleife geht vom Laden der Werte (bei mir in eax (array) und edx (i)) bis zum jnz ;) Steht (bei mir zumindest) sogar noch schoen in fett drueber, was gerade gemacht wird ;)

greetz
Mike

generic 20. Apr 2006 15:50

Re: Fehler in Delphi mit For-Schleife
 
warum nutzt du length?

funktioniert folgendes nicht?
Delphi-Quellcode:
for i:=low(arr) to high(arr) do

alcaeus 20. Apr 2006 16:16

Re: Fehler in Delphi mit For-Schleife
 
Zitat:

Zitat von generic
warum nutzt du length?

funktioniert folgendes nicht?
Delphi-Quellcode:
for i:=low(arr) to high(arr) do

Das macht es in diesem Fall nur noch schlimmer; weil die Optimierung dann evtl. zuschlaegt. Wenn du eine Array-Grenze kennst (z.B. weil du weisst dass das Array bei 0 losgeht), dann kannst du dir solche Aufrufe sparen, das kostet ja nur CPU-Zeit. Und wie gesagt, ich bin mir nicht sicher ob die Optimierung da noch losgeht ;)

Greetz
alcaeus

Luckie 20. Apr 2006 18:45

Re: Fehler in Delphi mit For-Schleife
 
Zitat:

Zitat von alcaeus
Das macht es in diesem Fall nur noch schlimmer; weil die Optimierung dann evtl. zuschlaegt.

Gerade das soll sie ja auch bei mir zu Demonstrationszwecken.

s.h.a.r.k 20. Apr 2006 20:50

Re: Fehler in Delphi mit For-Schleife
 
Ich bekomm echt die Krise... Ihr sagt doch, dass die Compiler-Optimierung bei mir zugeschlagen hat und da was verdreht hat. Wird diese Optimierung jedes mal bei mir angewandt oder kommt das jedes mal aufs neue drauf an.

Mir scheint, dass der Compiler da lustig ist und des macht wie er will... Einmal zählt er von oben nach unten, dann mal wieder so wie ich es gedacht habe, von 0 bis 5, dann mal wieder anders herum... Wieso? Nachdem ich jetzt meinen PC neu gestartet habe klappt es immer mit der for-Schleife. Aber wieso denn? Wenn dann muss es doch immer das selbe Phenomän sein oder?

mfg
shark

JasonDX 20. Apr 2006 20:58

Re: Fehler in Delphi mit For-Schleife
 
Sagen wirs so: Die Compileroptimierung ist so ausgelegt, dass sie keinen Einfluss auf die Ausgabe des Programms hat. Und soweit ich das beobachten konnte passt das auch.
Was das in diesem Thread (und dutzenden anderen) besprochene Phaenomen betrifft ist die Verwirrung die gestiftet wird, wenn optimierter Code debuggt wird. Der sieht naemlich ploetzlich etwas anders aus :shock: :stupid:
Er funktioniert auch etwas anders, das Ergebnis bleibt aber das selbe. Sollte es zumindest. Um rauszufinden, wo der Fehler jetzt liegt (an der Optimierung oder nicht) hilft es, einfach einmal die Schleife so zu probieren, und einmal mit ausgeschalteter Optimierung. {$O+/-} muesste AFAIR die denentsprechende Compiler-Direktive sein.
Wenn der Fehler tatsaechlich dort liegt (und es also ein reproduzierbarer Bug ist) kannst du den dann hier in der DP oder in der QualityCentral posten.

greetz
Mike


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz