Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Funktions-Parameter record: Call-by-value?? (https://www.delphipraxis.net/185476-funktions-parameter-record-call-value.html)

Bambi 15. Jun 2015 11:02

Delphi-Version: 5

Funktions-Parameter record: Call-by-value??
 
Hallo,
ich hab eine Klasse erstellt, die einen externen Event (Deklaration: "procedure OnEvent(Sender:TObject; Data: TMyDataRecord)") aufruft, um Daten an mein Hauptptogramm zu übergeben (Datenquelle ist ein UDP-Client, das Ereignis kommt also irgendwann...).
Meine Frage: die Daten werden ja in einem Record übergeben. Geschieht das per Call-On-Value (also wird der Record kopiert) oder per Call-On-Reference (nur die Referenz auf den Record wird übergeben).
Das Problem ist, dass ich im private-Bereich der Klasse ein Feld "FData: TMyDataRecord" deklariert hab, das die Daten sammelt und sobald alles vollständig ist das Event aufruft: "OnEvent(self, FData)". Call-On-Value wäre also angebracht.
BTW: Kann ich Call-On-Value nicht mit "const" vor dem Parameter erzwingen?

Danke und Gruß

Stephan

Mavarik 15. Jun 2015 11:07

AW: Funktions-Parameter record: Call-by-value??
 
Record ist keine Klasse!

Delphi-Quellcode:
type
  TFoo = Record
           A : Array[1..2000] of Byte;
         end;
var
  Foo : TFoo;
Foo ist der direkte Speicher und nicht ein Zeiger...

Wenn Du eine Procedure aufrufst und nicht VAR AFoo : TFoo an gibst ist es immer ein Call by Value

Mavarik

DeddyH 15. Jun 2015 11:22

AW: Funktions-Parameter record: Call-by-value??
 
Zitat:

Zitat von Mavarik (Beitrag 1305122)
Wenn Du eine Procedure aufrufst und nicht VAR AFoo : TFoo an gibst ist es immer ein Call by Value

Out und const zählen nicht (abgesehen davon, dass die im vorliegenden Fall nichts bringen)?

uligerhardt 15. Jun 2015 12:43

AW: Funktions-Parameter record: Call-by-value??
 
Parameter in Delphi werden immer by value übergeben, wenn man nicht var, out oder const verwendet. Das gilt für Skalare (Integer und so) ebenso wie für Records, und insbesondere auch für Klassenreferenzen (also z.B. AForm in
Delphi-Quellcode:
procedure Blubb(AForm: TForm)
). Bei letzteren entsteht nur gelegentlich Verwirrung, wenn jemand die Instanz der Klasse und die Referenz darauf verwechselt: Da die Referenz (per Wert!) übergeben wird, kannst du die Instanz verändern.

Mavarik 15. Jun 2015 14:04

AW: Funktions-Parameter record: Call-by-value??
 
Zitat:

Zitat von uligerhardt (Beitrag 1305133)
(also z.B. AForm in
Delphi-Quellcode:
procedure Blubb(AForm: TForm)
). Bei letzteren entsteht nur gelegentlich Verwirrung, wenn jemand die Instanz der Klasse und die Referenz darauf verwechselt: Da die Referenz (per Wert!) übergeben wird, kannst du die Instanz verändern.

OK um es einfacher aus zu drücken...

Wenn eine Klasse übergeben wird, wird "nur" der Zeiger(Pointer) übergeben...
Ob das nun per Referenz oder per Value ist, ist dabei egal, da der Pointer ja immer auf den gleichen Speicherbereich zeigt...

Mavarik

DeddyH 15. Jun 2015 15:25

AW: Funktions-Parameter record: Call-by-value??
 
Einspruch!
Delphi-Quellcode:
procedure NachWas1(AClass: TSomeClass);
begin
  AClass := nil;
end;
vs.
Delphi-Quellcode:
procedure NachWas2(var AClass: TSomeClass);
begin
  AClass := nil;
end;
Wo ist der Unterschied?

BUG 15. Jun 2015 15:26

AW: Funktions-Parameter record: Call-by-value??
 
Da kann man im Prinzip lange darüber streiten, ob Zeiger Referenzen oder Values sind. Letztendlich funktioniert die Übergabe von Parametern auf Instruktionsebene immer nur by-value; der Prozessor arbeitet erst einmal nur mit Werten. Alles darüber sind "nur" semantische Unterschiede, wenn auch nützliche. An der Stelle sollten wir uns aber nicht festbeißen.

Zitat:

Zitat von Bambi (Beitrag 1305120)
Geschieht das per Call-On-Value (also wird der Record kopiert) oder per Call-On-Reference (nur die Referenz auf den Record wird übergeben).
Das Problem ist, dass ich im private-Bereich der Klasse ein Feld "FData: TMyDataRecord" deklariert hab, das die Daten sammelt und sobald alles vollständig ist das Event aufruft: "OnEvent(self, FData)". Call-On-Value wäre also angebracht.
BTW: Kann ich Call-On-Value nicht mit "const" vor dem Parameter erzwingen?

Deine Überlegung ist vermutlich: Der Event-Handler soll nicht an dem Feld herummanipulieren dürfen, also möchte ich call-by-value.
Nun das Problem dabei: Wenn dein Record groß ist, dann wird das Kopieren des Records aufwendig. Was du tatsächlich möchtest, das ist eine schreibgeschützte Referenz auf das Record; und die bekommst du mit
Delphi-Quellcode:
const
. Sollte eine Kopie nötig sein, wird der Event-Handler das schon machen.

Mavarik 15. Jun 2015 15:41

AW: Funktions-Parameter record: Call-by-value??
 
Zitat:

Zitat von DeddyH (Beitrag 1305152)
Einspruch!

Dein Beispiel hat nix mir meiner Antwort zu tun...

Gemäß meiner Antwort wäre es eher so...

Delphi-Quellcode:
Procedure Foo(AFoo : TFoo);
begin
  Fillchar(AFoo,100,#0);
end;

Procedure Foo(Var AFoo : TFoo);
begin
  Fillchar(AFoo,100,#0);
end;
Mavarik

DeddyH 15. Jun 2015 15:43

AW: Funktions-Parameter record: Call-by-value??
 
Dann hat Deine Antwort aber wiederum nichts mit dem darin enthaltenen Zitat zu tun :tongue:


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:07 Uhr.

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