Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#25

Re: Function/Procedure -Deklaration ?!

  Alt 20. Apr 2004, 16:34
Moin!

Ok, ich habe das ganze jetzt nochmal debuggt und folgendes kam dabei raus: alle 3 Formen haben ein und die selbe Übergabeform:

EAX = Self der Form
EDX = Zeiger auf den String

Die Funktionen sind alle gleich vom Aufruf her - was durch den Variablentyp mit einer Grösse > 4 auch kein Wunder ist - vor allem wird bei Strings so oder so nur mit einer Instanzenaddresse gearbeitet.

Code:
  push ebp
  mov ebp, esp
  add esp, -$08  // Platz für 2x 4 Byte machen - sichern der Var's
  mov [ebp-$08], edx // String sichern auf'm Stack
  mov [ebp-$04], eax // Instanzenzeiger sichern auf'm Stack
 
  // hier ist ein Unterschied - siehe unten

  mov edx, [ebp-$08] // String holen
  mov eax, [ebp-$04] // Instanzenzeiger holen
  call Trim

...
Der Unterschied besteht bei der 1. Funktion wo kein Const und kein Var angeben wurde, dort wird vor dem Aufruf von Trim() sicher gestellt, dass es keine anderen Referenzen auf den String gibt - also wird, wenn eine Referenz da ist, diese abgespalten in einen eigenen String. Danach wird der eindeutige String nach dem Trim gelöscht - also Referenz entfernen und String löschen. Mit anderen Worten: Bei der ersten Form wird vorher keine Kopie von dem String gemacht, das macht die Funktion selber, wenn nötig - also wenn es mehr als eine Referenz auf den String gibt.

Mein Testcode dazu (Optimierung aus, sonst kann man das nicht so schön sehen)
Code:
Function Test1(AStr : String): String;
Begin
  Result := Trim(AStr);
End;

Function Test2(Const AStr : String): String;
Begin
  Result := Trim(AStr);
End;

Function Test3(Var AStr : String): String;
Begin
  Result := Trim(AStr);
End;

procedure TForm1.FormCreate(Sender: TObject);
Var
  s : String;
begin
  s := Edit1.Text;

  Label1.Caption := Test1(s);
  Label2.Caption := Test2(s);
  Label3.Caption := Test3(s);
end;
Zusammenfassung:

Die Aufrufart ohne Const oder Var sorgt für grösseren Code für die Duplizierung / Dereferenzierung. Die anderen beiden Arten sind völlig gleich. Und wohl gemerkt ist trotz des Unterschiedes kein Unterschied zwischen der by value oder by reference Übergabe zu sehen, weil die Übergabe der Parameter geschieht komplett gleich - die by reference Geschichte wird von der Funktion selber sicher gestellt.

MfG
Muetze1
  Mit Zitat antworten Zitat