Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi FOR-Schleifenvariable muss eine lokale Variable sein. Warum? (https://www.delphipraxis.net/7877-schleifenvariable-muss-eine-lokale-variable-sein-warum.html)

madbrain 23. Aug 2003 17:25


FOR-Schleifenvariable muss eine lokale Variable sein. Warum?
 
Moin, moin!

Ich habe relativ viele Prozeduren / Funktionen (in einer Unit) die einen Zähler brauchen. Um Variablen zu sparen, habe ich diese Variable global deklariert.
Delphi hält davon aber nicht so viel:


FOR-Schleifenvariable muss eine einfache lokale Variable sein

Diese Fehlermeldung wird angezeigt, wenn die Steuervariable einer for-Anweisung keine einfache Variable ist (sondern beispielsweise eine Komponente eines Datensatzes), und wenn sie nicht lokal zu der Prozedur ist, die die for-Anweisung enthält.

Aus Gründen der Abwärtskompatibilität ist es zulässig, eine globale Variable als Steuervariable zu verwenden – der Compiler gibt in diesem Fall eine Warnmeldung aus. Beachten Sie, dass mit Verwendung einer lokalen Variable außerdem ein leistungsfähigerer Programmcode erzeugt wird.


Die Idee, alles möglichst lokal zu deklarieren ist ja gut, aber in diesem Fall doch eher unpraktisch !?

Warum wird dadurch "leistungsfähigerer Programmcode" erzeugt? :?:

Thx

Madbrain

Hansa 23. Aug 2003 17:30

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Du mußt ausweichen auf eine WHILE oder REPEAT Schleife. Im Prinzip dasselbe, es sei denn Borland hat das in letzter Zeit geändert. Sieht aber wohl nicht so aus.

madbrain 23. Aug 2003 17:47

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
hmmm
ok danke. werd ich mal probieren, aber..

Warum???

Eine Repeat/While Schleife, ist doch im Prinzip auch nur ein For-Schleife mit einer anders formulierten Abbruchbedingung?

Hansa 23. Aug 2003 17:54

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Wenn Du
Delphi-Quellcode:
for i := 1 to 10000 do
schreibst wird das ganze 10000 mal durchlaufen, egal was in der Schleife passiert. Wahrscheinlich geht es um Compiler-Optimierung. Globale Variable belegen außerdem für die ganze Zeit des Programmlaufs Speicher, lokale eben nicht. und und und. Kümmere Dich einfach nicht darum und mache es eben anders. Um etwas mehr Denkarbeit wirst Du aber wohl nicht drumrum kommen. 8)

sakura 23. Aug 2003 19:53

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
:hi:
Zitat:

Zitat von madbrain
hmmm
ok danke. werd ich mal probieren, aber..

Warum???

Wie Hansa schon sagte, es handelt sich um eine Compiler-Optimierung. Intern wird I gar nicht für die Schleife benötigt, die Schleife wird durch das Register ECX gesteuert (dazu noch rückwärts). Wenn auf I zugegriffen wird, wird zusätzlich ein anderes Register herangezogen (i.A. EAX bzw EDX). Wenn I jetzt nicht lokal wäre, dann könnte ein zweiter Thread auf I zugreifen, um zu ermitteln wie der aktuelle Wert von I ist.

:arrow: Oops, I wird gar nicht genutzt, diese Abfrage würde fehlschlagen.

Um dieser Eventualität vorzubeugen muss I lokal sein. Aus gleichem Grund kann I auch innerhalb einer for-Schleife nicht manipuliert werden.

Die Antwort mag nicht befriedigend für Dein Problem sein, ist aber der Grund dazu. Ich würde Dir empfehlen for-Schleifen zu nutzen, die sind seit Delphi 3 oder 4 i.A. performanter als while- und repeat-Schleifen.

...:cat:...

Christian Seehase 23. Aug 2003 20:12

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Moin sakura,

fällt Dir eine Konstellation ein, bei der die Schleifenvariable in ECX liegt?

Ich hab's gerade noch einmal ausprobiert:

Fall 1 Optimierung ist ausgeschaltet:
Verwende ich i innerhalb der Schleife um den Wert ausgeben zu lassen (ShowMessage(IntToStr(i))), wird i in EBX gespeichert, weise ich i einer anderen Variablen zu, dann in EAX.
Wenn i innerhalb der Schleife nicht verwendet wird, dann liegt der Wert nur auf dem Stack und wird dort geändert und verglichen.
Interessanter Weise wird der Wert dann immer inkrementiert, und nicht dekrementiert.

Fall 2 Optimierung ist eingeschaltet:
i wird immer in EBX gespeichert. Wenn i nicht verwendet wird decrementiert, ansonsten inkrementiert.

sakura 23. Aug 2003 20:16

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Hi Christian,

:oops: da ist was durch einander geraten. Stimmt, EBX ist Standard, da EAX und EDX öfter während Operationen anderweitig genutzt werden. Was habe ich in dem Moment nur gedacht :wall: Aber der Rest war okay, oder :-D

...:cat:...

Hansa 23. Aug 2003 20:26

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
@Madbrain: siehste, das da habe ich befürchtet. :mrgreen: Und noch ein kleiner, allerdings wichtiger Hinweis: Nimm Sakura nicht zu wörtlich, wenn er sagt Du solltest eine for Schleife benutzen. Wenn Du vorher irgendwas mit 100 Zahlen machen mußt und es sind wirklich genau 100, eventuell weniger, dann nimm FOR. Ansonsten geht es NICHT mit for, sondern nur mit while/repeat. Eine andere Unsitte ist, falls es sich z.B. um 5-stellige Zahlen handelt, von denen wieder nur 100 gebraucht werden, so was zu tun:
Delphi-Quellcode:
for i := 1 to 99999 do
Kommen dann noch Festplattenzugriffe hinzu, na dann gute Nacht. 8)

Christian Seehase 23. Aug 2003 20:30

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Moin sakura,

das gemeine ist:
ECX zu nehmen wäre irgendwie logisch, da es hierfür ja einen Maschinenbefehl gäbe.

Mich hätte halt mal interessiert warum das nicht so ist. Ich vermute mal, dass darauf verzichtet wurde, weil sich dieser Befehl nur im verwenden liesse, wenn der Schleifenzähler in der Schleife nicht angesprochen wird.

JoelH 24. Aug 2003 08:03

hmm,
 
Zitat:

Zitat von madbrain
Die Idee, alles möglichst lokal zu deklarieren ist ja gut, aber in diesem Fall doch eher unpraktisch !?

Warum wird dadurch "leistungsfähigerer Programmcode" erzeugt? :?:

Thx

Madbrain

Es ist nicht unpraktisch, wieso auch ? Ist es so schwer immer die Zeile
Delphi-Quellcode:
 var i : integer;
zu tippen ?
zur not mach dir ein Shortcut.

Zum effizienteren Code. Ich denke globale Variablen werden in einem bestimmten Speicherbereich abgelegt der eventruell via FAR Calls etc. aufgerufen werden muss bzw. es durch ausvorkommen kann dass es so ist. Dadurch braucht der REchenr länger (auch wenn es nur einige Takte sind) um an die Werte zu kommen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:11 Uhr.
Seite 1 von 3  1 23      

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