Autor Beitrag
tuedeltue
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 10.09.13 14:39 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure WorkWithFiles(s: TStrings);
var i: Integer;
begin
for i := 0 to s.Count-1 do ShowMessage(s[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then WorkWithFiles(OpenDialog1.Files);
end;


So war mein Code und hat auch funktioniert. Jetzt wollte ich allerdings Speicher sparen und den Parameter als Referenz übergeben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure WorkWithFiles(var s: TStrings);
var i: Integer;
begin
for i := 0 to s.Count-1 do ShowMessage(s[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then WorkWithFiles(OpenDialog1.Files);
end;


Das bringt folgenden Fehler:
ausblenden Quelltext
1:
Constant object cannot be passed as var parameter					


Also hab ich folgendes geändert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure WorkWithFiles(p: Pointer);
var i: Integer;
begin
for i := 0 to TStringList(p^).Count-1 do ShowMessage(TStringList(p^)[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then WorkWithFiles(Addr(OpenDialog1.Files));
end;


So funktioniert es, aber - da ich mit Pointern nicht ganz vertraut bin wollte ich nachfragen - ist das so auch alles korrekt?
baumina
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 305
Erhaltene Danke: 61

Win 7
Delphi 10.2 Tokyo Enterprise
BeitragVerfasst: Di 10.09.13 15:01 
Soviel ich weiß, ist eine class (wie z.b. TStrings) bereits ein Pointer. Deswegen kannst dir das var und die pointerei sparen.
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Di 10.09.13 15:09 
Korrekt. Da werden keine Strings herumkopiert, da wird lediglich der Verweis auf die StringList weitergegeben.

Kleiner Tipp: Fange nicht an auf gut Glück RAM zu sparen, ohne dass du vorher entsprechende Probleme hattest ;-)
tuedeltue Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 10.09.13 17:00 
Aha, gut zu wissen! :wink: Aber prinzipiell war alles richtig, oder?
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 10.09.13 18:38 
Das würde ich nicht unterschreiben. Um Pointer (also auch Objektinstanzen) als Var- oder Out-Parameter zu übergeben, sollte man einen triftigen Grund haben, sonst kann man sich schnell selbst ins Knie schießen.
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 433
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Di 10.09.13 18:49 
user profile icontuedeltue hat folgendes geschrieben Zum zitierten Posting springen:
Aha, gut zu wissen! :wink: Aber prinzipiell war alles richtig, oder?


Jein.
Mit der Pointerlösung umgehst Du die Prüfungen des Compilers der ja zu Recht bei der Übergabe als VAR meckert.

Grund:
Files im Dialog ist zwar eine Stringlist, aber nur lesbar (da als Poperty ohne Setter realisiert).
Was als VAR übergeben wird muß prinzipiell auch beschreibbar sein.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 10.09.13 18:52 
AFAIK können Properties generell nicht als Var-Parameter übergeben werden, auch wenn ein Setter vorhanden ist.
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 433
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Di 10.09.13 18:54 
user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
AFAIK können Properties generell nicht als Var-Parameter übergeben werden, auch wenn ein Setter vorhanden ist.


Das ohnehin (ein VAR muß ein Speicherbereich sein, Properties können ja auch Procedures/Functions darstellen), meine Erklärung zielte auf die Compilermeldung bzgl. "constant" ab.
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 10.09.13 18:55 
Ah OK, dann sind wir uns ja einig :wink:
tuedeltue Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 11.09.13 19:26 
user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Jein. Mit der Pointerlösung umgehst Du die Prüfungen des Compilers der ja zu Recht bei der Übergabe als VAR meckert.


Das war schon so verstanden. Die Frage war, ob - von den möglichen Probleme beim Zugriff auf Properties via Pointer abgesehen - der Code zum Einsatz des Pointers korrekt ist. Aber ich interpretiere dein Jein mal entsprechend und denke also schon. :wink:

Zur ursprünglichen Frage: ich habe jetzt wieder Variante 1 von ganz oben im Code stehen. Das ist so also richtig und es gibt keine Verbesserungen, ja?
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mi 11.09.13 21:58 
nein, speicher kannst du 4 Byte sparen (den Pointer bzw. TStrings) indem du Work with Files direkt in Button1Click einbaust.
Aber wenn du für 4 Byte deinen kompletten Quelltext unübersichlich machen willst. Das ist nicht mein Code, den ich evt ín 1 jahr noch verstehen will :D#

P.S: ich bin mir nichtmal sicher ob du da 4 Byte sparst :D

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
glotzer
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: Mi 11.09.13 22:56 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
mir nichtmal sicher ob du da 4 Byte sparst :D

Soweit ich weiß nicht, da der erste Parameter Normalerweiße in einem Register steht. (glaub es war EAX)

_________________
ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
WasWeißDennIch
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Do 12.09.13 08:12 
Wie soll man da etwas sparen? Ein Pointer hat unter 32 Bit 4 Byte, eine Instanz ist intern ein Pointer, es sind also immer 4 Byte, egal ob ich die Referenz übergebe oder einen Pointer darauf. Das Problem bei einem Pointer als Var-Paramter ist doch, dass sich dieser innerhalb der verarbeitenden Routine ändern lässt und sich das auf das Original auswirkt. Somit kann es passieren, dass nach der Verarbeitung plötzlich ein ganz anderes Objekt angesprochen wird.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 14.09.13 12:44 
Also wenn, dann definiere deine Prozedur als inline.

ausblenden Delphi-Quelltext
1:
procedure WorkWithFiles(s: TStrings); inline;					


Dann wird der Inhalt der Funktion an der aufrufenden Stelle eingesetzt (als würde dort der Code selbst stehen, die Procedure wird sozusagen aufgelöst). Dann sparst du dir einen Funktionsaufruf, was dir etwas Rechenzeit sparen kann.

An sich geht es bei der Diskussion sowieso kaum um "Speicher" sparen, denn der Parameter wird ja ohnehin nur benötigt, solange die Prozedur läuft...und der Parameter kommt auf den Stack. Der Stack ist aber sowieso reserviert. Die "freien" Bytes kannst du also garnicht nutzen. Es geht bei call by reference (in Bezug auf Performanz) eher darum, dass nicht so viel Speicher geschrieben werden muss (also CPU-Zyklen) als um Speicherbedarf an sich.

Speicherverwaltung in Delphi (englisch):
delphi.about.com/od/...elphi-developers.htm

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)