Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Verständnisfrage zu Exit (https://www.delphipraxis.net/205711-verstaendnisfrage-zu-exit.html)

kagi3624 8. Okt 2020 14:44

Delphi-Version: 6

Verständnisfrage zu Exit
 
Als C/C++ Vorgeschädigter denke und schreibe ich immer noch ein result hin und erwarte das ende der Funktion. Nun, da Delphi ja bei einem result nicht die Funktion beendet, dachte ich exit zu benutzen, davor wird in der Delphi Basics Hilfe aber gewarnt. Was spricht eigentlich dagegen sowas zu schreiben und sich anzugewöhnen

Delphi-Quellcode:
if A then begin
  result := 1;
  exit;
end
else if B then...
Die ganzen nachkommenden else if Abfragen brauch ich ja nicht durchzugehen, wenn ich meine Funktion hier beenden will?

Delphi.Narium 8. Okt 2020 14:50

AW: Verständnisfrage zu Exit
 
Tust Du ja auch nicht:
Delphi-Quellcode:
if A then begin
  result := 1;
end
else if B then... // Else besagt doch: Nur wenn das vorherige nicht zutraf. Die Abfrage if b then wird also nicht ausgeführt.
Bei Deinem Beispiel ist das Exit schlicht überflüssig.

Der schöne Günther 8. Okt 2020 14:51

AW: Verständnisfrage zu Exit
 
Result in C++? Meinst du
Delphi-Quellcode:
return
?

Wie auch immer, gegen deinen Code spricht nichts. Außer dass du auch stattdessen schreiben könntest
Delphi-Quellcode:
Exit(1)
.


Zitat:

Zitat von Delphi.Narium (Beitrag 1475135)
Bei Deinem Beispiel ist das Exit schlicht überflüssig.

Wir wissen doch gar nicht ob seine Methode nur ein einziges if..else if.. else if... war oder ob da noch mehr kommt!

mkinzler 8. Okt 2020 14:51

AW: Verständnisfrage zu Exit
 
Wenn die Bedingung wahr ist wird das else eh nicht abgearbeitet.

stahli 8. Okt 2020 14:52

AW: Verständnisfrage zu Exit
 
Da gibt es unterschiedliche Auffassungen, die aber eher dem persönlichen Geschmack geschuldet sind.

Der Code sieht halt mit und ohne Exit unterschiedlich aus.
Funktionelle Probleme bzw. Fehler gibt es durch Exit jedoch nicht.

Du kannst mit Exit in einer Funktion auch direkt den Rückgabewert mitgeben.

Delphi-Quellcode:
if A then
begin
  Exit(1);
end
else
if B then...
Zu beachten ist, dass bei Exit in einem try-finally-Block in den finally-Abschnitt gesprungen wird (und danach - glaube ich - direkt aus der Methode).

Delphi.Narium 8. Okt 2020 14:54

AW: Verständnisfrage zu Exit
 
Naja, dann aber bitte so:
Delphi-Quellcode:
if A then Exit(1);
if B then...
Wenn ich schon mit Exit rausspringe, kann ich mir die nachfolgende Else sparen.

kagi3624 8. Okt 2020 14:57

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1475141)
Naja, dann aber bitte so:
Delphi-Quellcode:
if A then Exit(1);
if B then...
Wenn ich schon mit Exit rausspringe, kann ich mir die nachfolgende Else sparen.

Ja, genau so isses :thumb: Es gibt aber auch fälle, wo man auch ohne der if Abfrage raus will. In einer Schleife z.B.

stahli 8. Okt 2020 15:05

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1475141)
Naja, dann aber bitte so:
Delphi-Quellcode:
if A then Exit(1);
if B then...
Wenn ich schon mit Exit rausspringe, kann ich mir die nachfolgende Else sparen.

Das war doch nur ein symbolischer Auszug und keine vollständige Methode...

Delphi.Narium 8. Okt 2020 15:11

AW: Verständnisfrage zu Exit
 
Ja, aber hinter einem Exit in 'nem If then brauche ich keine Else. Die Alternative zu was soll denn da dann abgefragt werden, wenn die Alternative, zu der es ggfls. eine weitere geben könnte, bereits beschlossen hat, das hier ultimativ schluss iss? ;-)

@kagi3624
For-, Repeat, While-Schleifen kann man mit break verlassen.

Inhaltlich nicht sinnvoll, aber für's Prinzip geeignet ;)
Delphi-Quellcode:
for i := 0 to MaxInt do begin
  if i > Trunc(Now) then begin
    Result := i div 42;
    break;
  end;
end;

dummzeuch 8. Okt 2020 15:24

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von stahli (Beitrag 1475138)
Du kannst mit Exit in einer Funktion auch direkt den Rückgabewert mitgeben.

Delphi-Quellcode:
if A then
begin
  Exit(1);
end
else
if B then...

Aber mit Delphi 6, das er laut Profil einsetzt. Das kam erst in einer der XE-Versionen.

Benmik 8. Okt 2020 17:27

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1475141)
Wenn ich schon mit Exit rausspringe, kann ich mir die nachfolgende Else sparen.

Das sehe ich anders. Wenn ich einen (und womöglich längeren) Streifen mit
Delphi-Quellcode:
else
oder
Delphi-Quellcode:
end else if
habe, dann weiß ich sofort, dass nur einer dieser Blöcke ausgeführt wird. Bei deiner Notation springt dies nicht ins Auge, vielmehr erfährt man erst durch Auswerten, dass der nachfolgende Code nicht ausgeführt wird. Das empfinde ich als deutlich weniger intuitiv.

Delphi.Narium 8. Okt 2020 18:11

AW: Verständnisfrage zu Exit
 
Aber in der Situation ist das Exit nicht (zwingend) erforderlich, da die Routine ohne das Exit zum gleichen Ergebnis führen würde.

Schreibtechnisch wird also ein Result := 1 durch Exit(1) ersetzt.
Da finde ich die Zuweisung des Rückgabewertes an Result deutlich intuitiver als ein Exit, auch wenn es letztlich zum gleichen Ergebnis führt.

Exit nutze ich persönlich nur, wenn ich in 'ner Fehlersituation (also im Exceptblock eines Trys) aus 'ner Routine raus muss und damit sicherstellen will, das, egal, was später noch in 'ner Routine implementiert wurde, die Routine beendet wird.

Aber in 'ner If-else-if-Kasskade mit Exit auszusteigen, obwohl die Logik so implemtiert ist, dass das Exit nicht erforderlich ist, find' ich persönlich eher befremdlich.
Delphi-Quellcode:
function Test : Integer;
begin
  if a then begin
    Exit(1);
  end else
  if b then begin
    Exit(2);
  end else
...
  if z then begin
    Exit(26);
  end;
  // Jahre später wird in der Routine eine Änderung nötig, z. B. sowas:
  if (Result > 20) and (Result < 23) then begin
    // Mit Exit haben wir nun ein Problem, vor allem dann, wenn es nicht so offensichtlich ist, wie hier im Beispiel.
    // Mit der Nutzung von Result wäre es aber kein Problem.
  end;
end;
Und:

Wenn man Code nur intuitiv betrachtet und daraus Schlüsse zieht, kann man schonmal deutlich schiefliegen. Da ziehe ich die grundsätzliche Auswertung des Quelltextes doch vor.

Oder das ganze mal mit Case:
Delphi-Quellcode:
function Test(i : Integer) : Integer
begin
  case i of
    1      : Exit(1);
    2.. 10 : Exit(2);
   11..100 : Exit(3);
  else
    Exit(42);
  end;
end;
statt:
Delphi-Quellcode:
function Test(i : Integer) : Integer
begin
  case i of
    1      : Result := 1;
    2.. 10 : Result := 2;
   11..100 : Result := 3;
  else
    Result := 42;
  end;
end;
Geht beides, Variante 2 ist mir da aber deutlich lieber.

TurboMagic 8. Okt 2020 19:39

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1475136)
Result in C++? Meinst du
Delphi-Quellcode:
return
?

Wie auch immer, gegen deinen Code spricht nichts. Außer dass du auch stattdessen schreiben könntest
Delphi-Quellcode:
Exit(1)
.

Aber nur, wenn er von seinem Delphi 6 auf was neueres umsteigt.

himitsu 8. Okt 2020 22:32

AW: Verständnisfrage zu Exit
 
"Logisch" sind ELSE eigentlich passend,
auch wenn beim EXIT das ELSE unnötig wäre.

Wenn man aber mit ELSE und nur Result:= arbeitet, dann hat man z.B. die Chance ans Ende "einen" Haltepunkt zu setzen oder eine Loggingfunktion dort einzufügen, was bei den Exits (zentral) nicht ginge.


Was ich heute in der Hilfe vom VBScript sah .... im Delphi braucht man zum Glück nicht mehr
Delphi-Quellcode:
Funktionsname := ...;
und kann fehlerunanfäliger mit Result arbeiten. (sogar lesend)

Uwe Raabe 9. Okt 2020 00:01

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von himitsu (Beitrag 1475185)
Wenn man aber mit ELSE und nur Result:= arbeitet, dann hat man z.B. die Chance ans Ende "einen" Haltepunkt zu setzen oder eine Loggingfunktion dort einzufügen, was bei den Exits (zentral) nicht ginge.

Das Exit springt aber doch an das
Delphi-Quellcode:
end
der Function. Dort kannst du doch den Haltepunkt setzen.

himitsu 9. Okt 2020 00:05

AW: Verständnisfrage zu Exit
 
Nicht immer.
Keine lokalen Variablen und Dergleichen und schon kann Exit auch direkt rausspringen.

Uwe Raabe 9. Okt 2020 00:08

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von himitsu (Beitrag 1475193)
Keine lokalen Variablen und Dergleichen und schon kann Exit auch direkt rausspringen.

Hier geht es:
Delphi-Quellcode:
function MyFunc(Value: Integer): Integer;
begin
  if Value = 1 then
    Exit(1);
  if Value = 2 then
    Exit(2);
end;

Medium 9. Okt 2020 00:29

AW: Verständnisfrage zu Exit
 
Irgendwie habe ich den Eindruck, dass bisher im Thread die eigentliche "Gefahr" von Exit, mit oder ohne Return-Wert komplett übersehen wurde: Exit ist im Grunde nichts anderes als ein "goto" mit einem Label direkt vorm Methodenende. Exit begünstigt schlicht Spaghetti-Code, und erlaubt das Verlassen von Methoden/Funktionen/Prozeduren an Stellen, an denen es die sonstigen Kontrollstrukturen nicht offensichtlich erahnen lassen. Es ist einfach ein Wartbarkeits- bzw. Lesbarkeitsproblem, kein technisches oder logisches.

Ich persönlich nutze es nur gelegentlich, und dann auch nur gesammelt in den allerersten Zeilen einer Methode, wo ich gelegentlich abprüfe ob alle Bedingungen zur weiteren Verarbeitung der Methode gegeben sind. Und auch das meist nur in Legacy-Codes, wo eine wirklich "saubere" Lösung sehr unwirtschaftliche größere Restrukturierungen bedeuten würden. Und ich fühle mich schmutzig dabei.
Eine weitere Ausnahme sind Mini-Prozeduren, die aus maximal 10-15 Zeilen bestehen, die nur sehr kleine Aufgaben übernehmen. In diesen ist wenig genug Code, dass ein Exit nicht so leicht im allgemeinen Gewimmel untergeht, und gelegentlich zu weniger verschachteltem und besser lesbarem Code als die sonst nötigen Strukturen führt.

Rein technisch gesehen wäre es in 100% der Fälle vermeidbar; diese DIskussionen sind meiner Meinung nach hinfällig.

Delphi.Narium 9. Okt 2020 00:44

AW: Verständnisfrage zu Exit
 
:thumb:

Exit ist für mich im Großen und Ganzen ein Zeichen von unstrukturierter Programmierung, aber sicher kein empfehlenswerter Programmierstil. Les- und Wartbarkeit leiden, für meine Begriffe, extrem.

Benmik 9. Okt 2020 02:12

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Medium (Beitrag 1475195)
...in den allerersten Zeilen einer Methode, wo ich gelegentlich abprüfe ob alle Bedingungen zur weiteren Verarbeitung der Methode gegeben sind.

Ganz genau. Klassische Beispiele sind
Delphi-Quellcode:
If Dateiname = ''
oder
Delphi-Quellcode:
If not TFile.Exists(Dateiname)
da geht man einfach raus und das ist gut so. Auch ein GoTo ist nicht in 100% der Fälle schlecht, sondern nur in 99%, und in diesem einen Prozent macht es den Code besser und nicht schlechter, egal was der Pfarrer sagt. Zum Beispiel, wenn man aus verschachtelten Schleifen herausspringt, wenn ein bestimmtes Ergebnis auf kompliziertem Weg gefunden wurde. Kein Mensch kann mir erzählen, dass es einen gestandenen Programmierer in Verwirrung stürzt, wenn am Ende einer Schleife ein Label
Delphi-Quellcode:
Weiter:
oder
Delphi-Quellcode:
Nächster Durchlauf:
oder
Delphi-Quellcode:
MachsNochEinmalSam:
steht. Es sind eher die Verrenkungen, die man betreibt, um zu beweisen, dass es auch mit der ganz ganz reinen Lehre geht, die den Code schlechter machen. Mein ich aus meiner bescheidenen Amateursicht.

Wenn man hier schon der Hohepriesterei der Lesbarkeit und Übersichtlichkeit huldigt, warum hält dann die ganze Delphizunft an diesem unsäglichen
Delphi-Quellcode:
If Bedingung1 then
  begin
    Mach1;
  end
else
if Bedingung2 then
  begin
    Mach2;
  end
else
  begin
    MachNix;
  end;
fest?
Man vergleiche das mit
Delphi-Quellcode:
If Bedingung1 then begin
  exit;
end else if Bedingung2 then begin
  Mach2;
end else if Bedingung3 then begin
  Mach3;
end else begin
...
end;
Kein Mensch, wirklich keiner, würde auf die Idee kommen, das anders zu machen, wenn man nicht in eine Zunft reinkäme, die nunmal darauf geeicht ist.
Mit Genugtuung sehe ich immer, dass ausgerechnet David Heffernan es auch auf die zweite Weise macht, und hier gilt das für Thomas Müller (dummzeuch) ebenso. Heffernan geht so weit, dass er überhaupt kein einfaches "then" mehr benutzt, sondern ausschließlich "then begin". Jetzt ist nicht alles richtig, nur weil David Heffernan es so macht, aber offensichtlich kann man auch so lesbaren und guten Code schreiben. Jedenfalls warte ich noch auf den Tag, an dem einer aufsteht und David mal Bescheid sagt.

Ich finde die Methode 2 weder böses GoTo noch Spaghetticode oder sonstwas, sondern nur eins: Sehr übersichtlich. Es spielt - in meinen Augen - überhaupt keine Rolle, dass das "end else" nach dem "exit" technisch nicht notwendig ist: Na und? Man sieht auf einen Blick: Es gibt da 3 oder 5 oder auch 8 Zustände, die zu 3 oder 5 oder 8 Reaktionen führen, einer oder meinetwegen auch 3 oder 7 davon bedeuten "exit". "Exit" ist eine völlig legitime Konsequenz, was daran schlecht oder gar schmutzig sein soll, erschließt sich mir nicht so ganz.

Jetzt habe ich mich ein bisschen ereifert, da bitte ich um Nachsicht.

venice2 9. Okt 2020 03:33

AW: Verständnisfrage zu Exit
 
Zitat:

Jetzt habe ich mich ein bisschen ereifert, da bitte ich um Nachsicht.
Kein Problem nur warum überhaupt ein "begin"

Delphi-Quellcode:
If Bedingung1 then
  exit
else if Bedingung2 then
  Mache2
else if Bedingung3 then
  Mach3
else
...
zudem würde ich solche Verschachtelungen gar nicht verwenden sondern direkt mit Case arbeiten.

Delphi-Quellcode:
case Bedingung of
  1:
    exit;
  2:
    Mache2;
  3:
    Mache3;
  else
    was auch immer
end;

HeZa 9. Okt 2020 07:47

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von venice2 (Beitrag 1475200)
Kein Problem nur warum überhaupt ein "begin"

Da bin ich bei dir. Zur Not könnte man den Code aus den begin-end Blöcken in kleine lokale Proceduren/Funktionen packen.
Zitat:

Zitat von venice2 (Beitrag 1475200)
zudem würde ich solche Verschachtelungen gar nicht verwenden sondern direkt mit Case arbeiten.

Da es unterschiedliche Bedingungen sein könnten, ist ein case nicht immer möglich.

mkinzler 9. Okt 2020 07:55

AW: Verständnisfrage zu Exit
 
Zitat:

Ich finde die Methode 2 weder böses GoTo noch Spaghetticode oder sonstwas, sondern nur eins: Sehr übersichtlich.
Ich bevorzuge eher begin und end auf selber (Einrückungs-)Ebene.

Zitat:

Kein Problem nur warum überhaupt ein "begin"
Damit man es nicht später vergisst. (wenn dann die Sequenz erweitert wird)
Zitat:

Zur Not könnte man den Code aus den begin-end Blöcken in kleine lokale Proceduren/Funktionen packen.
Warum nur zur Not? Hängt eher vom Unfang/Länge der Sequenz( Block) ab und ob er vielleicht wo anders noch benötigt wird.

dummzeuch 9. Okt 2020 09:50

AW: Verständnisfrage zu Exit
 
Juchu, lasst uns noch eine Diskussion um Goto und Goto-ähnliche Konstrukte führen! Das hatten wir schon lange nicht mehr. ;-)

Meine Meinung:
Im Gegensatz zu Continue, Break und einem Goto, ist Exit ein relativ harmloses Konstrukt und hat definitiv seine Anwendung. Insbesondere verwende ich es gern, um am Anfang einer Methode die Eingangs-Voraussetzungen (Parameter, Zustand des Objekts) zu prüfen und die Methode dann zu verlassen, wenn es nichts zu tun gibt.

Delphi-Quellcode:
procedure bla(const _s: string);
begin
  if _s = '' then begin
    // ein leerer String braucht nicht verarbetet zu werden.
    Exit; //==>
  end;
  // irgendwas längeres mit _s machen
end;
oder
Delphi-Quellcode:
procedure TSomeObject.SetVisibiel(_Value: boolean);
begin
  if _Value = FVisible then begin
    // keine Änderung -> raus
    Exit; //==>
  end;

  FVisible := _Value;
  // jetzt noch alles mögliche andere machen
end;
Dieses "Early Return" wird durchaus häufig verwendet, ist aber nicht ganz umstritten.

Dann gibt es noch eine andere praktische Verwendung von Exit: Das frühzeitige Verlassen von Schleifen:
Delphi-Quellcode:
function FindMatchingString(_sl: TStringList; const _s: string; out _Idx: Integer): boolean;
var
  i: Integer;
begin
  for i := 0 to _sl.Count -1 do begin
    if StartsText(_s, _sl[i]) then begin
      _Idx := i;
      Result := True;
      Exit; //==>
    end;
  end;
  Result := False;
end;
Natürlich könnte man da auch Break verwenden, aber die Erfahrung hat mich gelehrt, dass ein Break gerne mal nicht die Schleife beendet, von der man denkt, dass sie beendet wird. Nachdem ich zum x-ten Mal irgendo eine geschachtelte Schleife eingebaut hatte und Break dann plötzlich nur noch diese innere Schleife verlasen hat, habe ich mir komplett abgweöhnt, es zu verwenden. Dito Continue.

Ach ja, und dann gibt es da immernoch das einzige Goto in unserer Codebase, das ich vor 13 Jahren eingebaut habe und jetzt schon aus Trotz drin lassen werde. ;-)

Medium 9. Okt 2020 10:03

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von dummzeuch (Beitrag 1475213)
Delphi-Quellcode:
function FindMatchingString(_sl: TStringList; const _s: string; out _Idx: Integer): boolean;
var
  i: Integer;
begin
  for i := 0 to _sl.Count -1 do begin
    if StartsText(_s, _sl[i]) then begin
      _Idx := i;
      Result := True;
      Exit; //==>
    end;
  end;
  Result := False;
end;

Da sollte dir der Compiler um die Ohren hauen, dass das Funktionsergebnis undefiniert sein kann. Setze das Result := false; an den Anfang der Funktion, und sie ist okay.

Dennoch finde ich GERADE hier Exit sau gefährlich! Da muss nur einer mal auf die Idee kommen, noch Code hinter die Schleife zu packen, der auf jeden Fall durchlaufen werden soll.

Continue und Break haben sich bei mir bisher immer brav verhalten. Was unheimlich hilft dabei, ist es die Schleifenrümpfe brav alle in begin..end Blöcke zu verpacken, sodass der Scope immer eindeutig ist - auch optisch.

Uwe Raabe 9. Okt 2020 11:02

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Medium (Beitrag 1475214)
Da sollte dir der Compiler um die Ohren hauen, dass das Funktionsergebnis undefiniert sein kann.

Wieso? Ich sehe da keinen möglichen Code-Path, der die Funktion ohne Setzen von Result verlässt.

bcvs 9. Okt 2020 11:02

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von dummzeuch (Beitrag 1475213)
Insbesondere verwende ich es gern, um am Anfang einer Methode die Eingangs-Voraussetzungen (Parameter, Zustand des Objekts) zu prüfen und die Methode dann zu verlassen, wenn es nichts zu tun gibt.

Delphi-Quellcode:
procedure bla(const _s: string);
begin
  if _s = '' then begin
    // ein leerer String braucht nicht verarbetet zu werden.
    Exit; //==>
  end;
  // irgendwas längeres mit _s machen
end;

Genau für diesen Fall verwende ich Exit auch ganz gerne. Auch weil es eine Einrückungsebene spart. Die Alternative wäre ja:

Delphi-Quellcode:
procedure bla(const _s: string);
begin
  if _s <> '' then begin
    // irgendwas längeres mit _s machen
  end;
end;

Medium 9. Okt 2020 11:07

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1475216)
Zitat:

Zitat von Medium (Beitrag 1475214)
Da sollte dir der Compiler um die Ohren hauen, dass das Funktionsergebnis undefiniert sein kann.

Wieso? Ich sehe da keinen möglichen Code-Path, der die Funktion ohne Setzen von Result verlässt.

Oh, du hast Recht. Vor dem Exit MUSS ja result := true passieren. Mea culpa. Dennoch finde ich es unschön in diesem Fall.

DasWolf 9. Okt 2020 11:16

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Medium (Beitrag 1475214)
Setze das Result := false; an den Anfang der Funktion, und sie ist okay.

Nein, Nein, Nein und nochmal Nein. Das Result wird nicht am Anfang belegt.

Medium 9. Okt 2020 11:22

AW: Verständnisfrage zu Exit
 
Warum das denn?

stahli 9. Okt 2020 11:23

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von DasWolf (Beitrag 1475219)
Nein, Nein, Nein und nochmal Nein. Das Result wird nicht am Anfang belegt.

Die Zuweisung am Anfang zu erzwingen ist genau so Unsinn wie das zu verweigern.
Es kommt doch immer auf den Einzelfall an. Darüber hinaus spielen dann auch noch persönliche Vorlieben oder Vorgaben in einer Firma hinein.

Darüber zu streiten macht keinen Sinn.

DasWolf 9. Okt 2020 12:09

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Medium (Beitrag 1475220)
Warum das denn?

Alt, aber da halte ich mich immer noch dran: https://www.delphipraxis.net/85402-post.html#93878

Uwe Raabe 9. Okt 2020 12:42

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von DasWolf (Beitrag 1475223)
Alt, aber da halte ich mich immer noch dran: https://www.delphipraxis.net/85402-post.html#93878

Ich denke, da geht es eher darum das Result als lokale Variable zu missbrauchen. Das hat aber eher was mit Performance zu tun als mit gutem oder schlechtem Programmierstil.

Benmik 9. Okt 2020 13:08

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von DasWolf (Beitrag 1475219)
Nein, Nein, Nein und nochmal Nein. Das Result wird nicht am Anfang belegt.

Das ist es, was mich so ganz allgemein stört: Warum gibt es im Programmiererclub mehr Dogmen als in der katholischen Kirche, und auch mehr Inquisitoren? Und warum sind die angeführten Gründe für diese Dogmen oft so wie der Beweis der Jungfräulichkeit Mariae? Wie bei Maria spricht viel mehr für die umgekehrte Ansicht.

Rollo62 9. Okt 2020 15:04

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Benmik (Beitrag 1475235)
Warum gibt es im Programmiererclub mehr Dogmen als in der katholischen Kirche

Gibts doch gar nicht: Ich mach was mir gefällt

Tralla li tralla la, tralla hopsassa :stupid:

Rollo62 9. Okt 2020 15:09

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Benmik (Beitrag 1475235)
Warum gibt es im Programmiererclub mehr Dogmen als in der katholischen Kirche,

Aber Du hast sicher Recht, ein bischen lockerer könnten die Puristen schon werden.

Result als lokale Variable:
- Ja, da wo es Sinn macht

Exit als Vorbedingung
- Ja, wenn es zig Verschachtelungen vermeidet

...
...
...

Habe ich theroretische Philosophieprobleme damit ?
Nein, wenn ich weiss was ich da tue.


Ausserdem versuche ich es möglichst gut visuell zu dokumentieren:
Delphi-Quellcode:
begin
   if VorbedingungFails then
   begin
      Exit; //<== Leave here ==============================================
   end;

  ...
end;

Stevie 9. Okt 2020 16:11

AW: Verständnisfrage zu Exit
 
Zu "Exit ist genauso böse wie goto" - sehe ich nicht so - Exit hat ein unverrückbares Ziel: das Ende der Routine, wohingegen zu einem goto immer ein label gehört, was sonstwo sein kann.

Zu "Result erst so spät wie möglich setzen" - ja, das verhindert, dass der Compiler den Wert für eine Weile merken und zwischenspeichern muss, entweder auf dem Stack oder er blockiert ein Register, was dann woanders fehlt. Aber wenn man bei dieser Argumentation ist, dann muss man noch ganz viele andere Dinge beachten und sich fragen, ob man das dann macht, wenn man genau weiß warum oder einfach nur "cargo cult" folgt.

Zu "Exit benutzen oder nicht" - teilweise Geschmackssache, ich nutze gern ein Exit aus einer "suche mir ein Element"-Schleife und handhabe den "kein Fund"-Fall einfach nach der Schleife. Oder ich verabschiede mich nach einigen anfänglichen negativ formulierten Überprüfungen gleich mit einem Exit, so dass ich den ganzen eigentlichen Code nicht unterhalb der positiv formulierten Bedingung in einem Block habe (sofern nicht absolut optimiert, denn da gelten wieder andere Regeln - Stichwort branchless programming bzw common path ohne conditional jump taken).

Eine Sache noch zu Exit oder nicht - die Benutzung von Exit kann durchaus dafür sorgen, dass der Compiler auch tatsächlich an dieser Stelle ein ret einbaut wohingegen der Fall mit einem else... ein jmp an das end der Routine erfolgt.

Andreas13 9. Okt 2020 17:45

AW: Verständnisfrage zu Exit
 
Hallo,
auch ich benutze Exit bei numerischen Berechnungen recht oft, häufig in folgender beispielhafter Weise:

Delphi-Quellcode:
Function Komplizierte_Berechnung(CONST a, b, c: Extended;
            CONST X_Vektor, Y_Vektor, Z_Vektor: TExtended_Array;
                                  VAR A_Matrix: TExtended_Matrix;
                                   VAR f, g, h: Extended): Integer;
VAR
  Diverse dynamische Strukturen;

Begin
  Dynamische Strukturen initialisieren;
  . . .
  Try
    IF NOT Check_1(...) Then
    Begin
      Exit(ErrorCode_1);
    End;


    IF NOT Check_2(...) Then
    Begin
      Exit(ErrorCode_2);
    End;
    . . .

    IF Bedingung_1 Then
    Begin
      Berechnungen_1;
      Exit(ErrorCode_3);
    End;

    IF Bedingung_2 Then
    Begin
      Berechnungen_2;
      Exit(ErrorCode_4);
    End;

    . . .

  Finally
    Rückgabeparameter schreiben;
    Dynamische Strukturen freigeben;
  End;
End;
Ich habe damit gute Erfahrungen gemacht.
Gruß, Andreas

Medium 9. Okt 2020 21:23

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Stevie (Beitrag 1475247)
Zu "Exit ist genauso böse wie goto" - sehe ich nicht so - Exit hat ein unverrückbares Ziel: das Ende der Routine, wohingegen zu einem goto immer ein label gehört, was sonstwo sein kann.

Zu "Result erst so spät wie möglich setzen" - ja, das verhindert, dass der Compiler den Wert für eine Weile merken und zwischenspeichern muss, entweder auf dem Stack oder er blockiert ein Register, was dann woanders fehlt. Aber wenn man bei dieser Argumentation ist, dann muss man noch ganz viele andere Dinge beachten und sich fragen, ob man das dann macht, wenn man genau weiß warum oder einfach nur "cargo cult" folgt.

Zu "Exit benutzen oder nicht" - teilweise Geschmackssache, ich nutze gern ein Exit aus einer "suche mir ein Element"-Schleife und handhabe den "kein Fund"-Fall einfach nach der Schleife. Oder ich verabschiede mich nach einigen anfänglichen negativ formulierten Überprüfungen gleich mit einem Exit, so dass ich den ganzen eigentlichen Code nicht unterhalb der positiv formulierten Bedingung in einem Block habe (sofern nicht absolut optimiert, denn da gelten wieder andere Regeln - Stichwort branchless programming bzw common path ohne conditional jump taken).

Eine Sache noch zu Exit oder nicht - die Benutzung von Exit kann durchaus dafür sorgen, dass der Compiler auch tatsächlich an dieser Stelle ein ret einbaut wohingegen der Fall mit einem else... ein jmp an das end der Routine erfolgt.

Hier kann ich in allen Punkten volle Zustimmung geben und Fanboy-Flaggen wedeln. *wedel*

himitsu 9. Okt 2020 22:20

AW: Verständnisfrage zu Exit
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1475229)
Ich denke, da geht es eher darum das Result als lokale Variable zu missbrauchen. Das hat aber eher was mit Performance zu tun als mit gutem oder schlechtem Programmierstil.

Ich sehe das sogar eher andersrum.

Empfinde es schlecht hässlich, wenn man sinnlos eine weitere Variable benutzt, anstatt direkt Result.

Und von der Preformance her ist das kein Unterschied.
Es kann sogar sein, dass die zusätzliche Variable mehr speicher benötgt, wenn es für den Compiler nicht möglich ist, die Resultvariable (deren Speicherplatz) erst ab der Stelle der Zuweisung zu reservieren.


Es gibt aber Einwas, wo man das als Nachteil betrachten könnte.
Denn z.B. ein Result als Interface oder String, wird vom Compiler als VAR-Parameter behandelt.
Kommt es dann zu einer Exception, dann würde die äußere Variable (da wo das Result der Funktion zugewiesen werden sollte) bereits verändert sein, was man so nicht direkt erwarten würde.

Delphi-Quellcode:
function MyFunc: string;
begin
  Result := '2';
  raise Exception.Create('');
end;

procedure Test;
var
  X: string;
begin
  X := '1';
  try
    X := MyFunc;
  except
    ShowMessage(X);
  end;
end;
Das selbe Beispiel mit Integer als Variable/Result, da bleibt es "1", da an "X" ja noch nchts zugewiesen wurde, weil es "vorher" abgeraucht ist.

Für mich sind nach einer Exception Results von jeglichen Funktionen sowieso als "ungültig" anzusehen, somit gibt es IMHO damit eigentlich auch keine Probleme.


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:09 Uhr.
Seite 1 von 2  1 2   

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