Delphi-PRAXiS
Seite 3 von 10     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Procedure vs Function, Vor- und Nachteile (https://www.delphipraxis.net/196015-procedure-vs-function-vor-und-nachteile.html)

himitsu 15. Apr 2018 16:14

AW: Procedure vs Function, Vor- und Nachteile
 
Delphi-Quellcode:
function Test: Integer;
begin
  Result := Result + 1;
end;
Delphi-Quellcode:
function Test: string; // procedure Test(var Result: string);
begin
  Result := Result + 'a';
end;
Genau das sagte ich doch.
Bei Ersten kommt die Fehlermeldung, da der Integer wirklich als lokale Variable existiert, als Result in EAX zurückgeliefert und anschließend der äußeren Variable zugewiesen wird.
Während beim String (vom Compiler speicherverwalteter Zeigertyp) keine lokale Variable existiert und direkt in den referenzierten Parameter geschrieben wird.

Delphi-Quellcode:
function Test: Integer;
begin
  Result := Result + 1;
  raise Exception.Create('');
end;

i := 123;
try
  i := Test;
except
end;
ShowMessage(i.toString); // immer 123
Delphi-Quellcode:
function Test: string; // procedure Test(var Result: string);
begin
  Result := Result + 'a';
  raise Exception.Create('');
end;

s := 'x';
try
  s := Test;
except
end;
ShowMessage(S); // je nach Compileroptiomierung auch mal 'xa' und nicht 'x'
Hängt davon ab, ob der Compiler für das Result automatisch eine lokale Variable erstellt und anschließend umkopiert oder direkt das Result nimmt.
Delphi-Quellcode:
s := 'x';
try
  Test(temp); // temp := Test;
  s := temp;
except
end;

// oder

s := 'x';
try
  Test(s); // s := Test;
except
end;
In einer Schleife mehrfach Test aufgerufen bekommt die Funktion aber praktisch immer wieder die selbe Variable rein.

KodeZwerg 15. Apr 2018 17:11

AW: Procedure vs Function, Vor- und Nachteile
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1399318)
in den Projektoptionen unter Compilermeldungen auswählen, ob die Warnung 'Dr Rückgabewert der Funktion könnte undefiniert sein.'

Verzeih das ich jetzt erst darauf reagiere, Mittagessen, Füße hoch und so :)
Danke für den Tipp, ich habe auch probiert Ihn umzusetzen, nun hab ich alle Meldungen On/Off durch mit dem Resultat wie himitsu schrieb, es gibt keine Warnung für das
Delphi-Quellcode:
procedure Test(var Result: string); begin Result := Result + 'a'; end;
Beispiel.
Dennoch Danke! Auch nochmal an himitsu für die vielen Beispiele und Erklärungen!

Zacherl 15. Apr 2018 18:22

AW: Procedure vs Function, Vor- und Nachteile
 
Zitat:

Zitat von Redeemer (Beitrag 1399295)
Zitat:

Zitat von Zacherl (Beitrag 1399294)
Ziemlich wurscht. Wenn man einen Rückgabewert hat, sind Funktionen zu bevorzugen, da sie intuitiver sind und genau für diesen Zweck entwickelt wurden. In seltenen Fällen (bei Übergabe großer Strukturen bzw. Strings, etc.) kann ein
Delphi-Quellcode:
var
Parameter sinnvoll sein, um Kopieroperationen zu vermeiden. Muss man sich im Normalfall aber keine Gedanken drüber machen.

Da hast du
Delphi-Quellcode:
var
mit
Delphi-Quellcode:
const
verwechselt.

Delphi-Quellcode:
var
ist genau wie (meistens)
Delphi-Quellcode:
const
ein "pass by reference", also stimmt das schon mit der Vermeidung von unnötigen Kopieroperationen. Da ein Output Parameter ja aber gewünscht ist, macht
Delphi-Quellcode:
const
hier keinen Sinn :gruebel:

Zitat:

Zitat von Redeemer (Beitrag 1399295)
Zudem verwechselt ihr beide
Delphi-Quellcode:
var
mit
Delphi-Quellcode:
out
.

Nöö.
Delphi-Quellcode:
var
ist runtergebrochen auf den generierten Code exakt gleichwertig zu
Delphi-Quellcode:
out
(auch wenn out gegebenenfalls aus Gründen der Übersichtlichkeit zu bevorzugen ist).

Code:
005CE2D4 E8BFFFFFFF      call Beispiel1 // function
Unit2.pas.48: Beispiel2(X);
005CE2D9 8D45FB          lea eax,[ebp-$05]
005CE2DC E8C7FFFFFF      call Beispiel2 // procedure mit var
Unit2.pas.49: Beispiel3(X);
005CE2E1 8D45FB          lea eax,[ebp-$05]
005CE2E4 E8CFFFFFFF      call Beispiel3 // procedure mit out
Zitat:

Zitat von himitsu (Beitrag 1399299)
bei gemanagten Typen ala String, Variant, Interface und dynamischen Arrays macht der Delphi-Compiler aus
Delphi-Quellcode:
function Beispiel(...): string;
eben auch ein
Delphi-Quellcode:
procedure Beispiel(...; var Result: string);
und kopiert nichts um

Interessant. So viel "Intelligenz" hätte ich dem Delphi Compiler ernsthaft nicht zugetraut. Wieder was gelernt.

himitsu 15. Apr 2018 19:07

AW: Procedure vs Function, Vor- und Nachteile
 
Prozedur für Füllen von Objekten ala Listen, wo es als Result oft ungünstig ist.

Und Prozedur hat eher Nachteile, denn du brauchst da immer eine "selbstdefinierte" Variable und man kann es nicht direkt weitergeben, z.B. als Parameter an eine andere Prozedur/Funktion oder für's Zusammenrechnen mehrerer Werte ohne Zwischenvariablen.

himitsu 15. Apr 2018 19:09

AW: Procedure vs Function, Vor- und Nachteile
 
VAR und OUT ist praktisch das Gleiche, außer dass bei OUT per Definition kein Eingabewert existiert, also die Variable initialisiert werden müsste, aber für Typen ala String/Array/Interface bricht der Compiler dieses, da sonst die ordnungsgemäße Speicherverwaltung nicht mehr garantiert werden kann.

KodeZwerg 15. Apr 2018 19:55

AW: Procedure vs Function, Vor- und Nachteile
 
und das man bei OUT innerhalb der procedure/function nicht lesend darauf zugreifen sollte, so hab ich das verstanden, richtig?

himitsu 15. Apr 2018 20:16

AW: Procedure vs Function, Vor- und Nachteile
 
Man darf, vor allem nachdem man schon etwas zugewiesen hat.

Vor der ersten Zuweisung ist der Wert einfach "undefiniert", so wie bei lokalen Variablen (Integer und so).

KodeZwerg 15. Apr 2018 20:22

AW: Procedure vs Function, Vor- und Nachteile
 
Danke, ich habe das mit VAR und OUT nun dank Euch/Dir verinnerlicht! Super Forum & Super Community, ich freue mich hier sein zu dürfen.

Ghostwalker 16. Apr 2018 05:47

AW: Procedure vs Function, Vor- und Nachteile
 
Das die Warnung bei gemanagten Datentypen garnicht erscheint ist mir ehrlich gesagt bisher nicht aufgefallen:oops:.

Das mit var und out war mir bisher auch nicht bewußt, da ich in der Regel bei solchen Fällen
immer var benutzt habe. Man lernt nie aus :)

In den letzten Versionen scheint sich da auch (positiv) am Compiler doch einiges geändert zu haben, denn
selbst in folgendem Fall, erkennt der Compiler, das result nicht undefiniert sein kann (war schonmal anders :)).

Delphi-Quellcode:
function Test(wupti:boolean):integer;
begin
  if (wupti) then
    result := 1
  else
    result := 0;
end;

bernau 16. Apr 2018 08:28

AW: Procedure vs Function, Vor- und Nachteile
 
Zitat:

Zitat von himitsu (Beitrag 1399299)
Zitat:

Zitat von Zacherl (Beitrag 1399294)
In seltenen Fällen (bei Übergabe großer Strukturen bzw. Strings, etc.) kann ein
Delphi-Quellcode:
var
Parameter sinnvoll sein, um Kopieroperationen zu vermeiden. Muss man sich im Normalfall aber keine Gedanken drüber machen.

Gerade da ist es total wurscht,
denn bei gemanagten Typen ala String, Variant, Interface und dynamischen Arrays macht der Delphi-Compiler aus
Delphi-Quellcode:
function Beispiel(...): string;
eben auch ein
Delphi-Quellcode:
procedure Beispiel(...; var Result: string);
und kopiert nichts um.

Leider ist das auch das Problem/die Urache, dass bei Funktionen für das Result keine "wurde nicht initialisiert"-Meldung vom Compiler kommt, da es eben doch initialisiert wurde (außerhalb)
und mit dem Ergebnis, dass bei vergessenen Initialisierung schnell etwas Komisches heraus kommt,
Delphi-Quellcode:
function Test: string;
begin
  Result := Result + 'a';
end;

for i := 1 to 5 do
  S := Test;
ShowMessage(S); // 'aaaaa'
aber wenn man sich das jetzt gedanklich als Prozedur ansieht, dann ist sofort klar, warum es so ist.

Damit würde ich aber schlaflose Nächte haben.

Result ist definitiv nicht initialisiert und besitzt einen Zufallswert, der ggf. dann von dem vorherigen Funktionsaufruf noch zufällig vorhanden ist.

Mag sein, dass das jetzt so funktioniert. Dieses Verhalten ist aber nirgends dokumentiert. (Oder ich habe es noch nicht gesehen.)

Bei einer nächsten Compilerfunktion wird das ggf. ganz anders sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:12 Uhr.
Seite 3 von 10     123 45     Letzte »    

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