Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Function Result (https://www.delphipraxis.net/127716-function-result.html)

API 17. Jan 2009 21:07


Function Result
 
Guten Abend!

Eine Funktion abc soll False zurückgeben, wenn zwischen try..finally ein Fehler auftritt.
Warum erhalte ich den Hinweis?

Zitat:

[Hint] unit1.pas(83): Value assigned to 'abc' never used
Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObjectX;
begin
  Result := False;
  Obj := TObjectX.Create;
  with Obj do
  try
    // ..
    // ..
    // ..
    // ..
    // ..
    // ..
    // ..
    Result := True;
  finally
    Free;
  end;
end;

omata 17. Jan 2009 21:09

Re: Function Result
 
Vielleicht, weil du die Funktion noch nirgends benutzt?

sirius 17. Jan 2009 21:12

Re: Function Result
 
Das Result:=false wird nie benutzt. Weil, wenn ein Fehler auftritt, wird erstmal in den Finally-block gesprungen und dann ganz raus und keiner interessiert sich mehr für das Ergebnis von abc.

mr_emre_d 17. Jan 2009 21:13

Re: Function Result
 
Delphi-Quellcode:
function abc: Boolean;
begin
  Result := False;
  with TObjectX.Create do
  begin
    try
      try
        // ..
        Result := True;
      except
        // Result := False --> überflüssig
      end;
    finally
      Free;
    end;
  end;
end;
Machs lieber so ;)

EDIT: Ups .. war einer schneller

API 17. Jan 2009 21:15

Re: Function Result
 
Zitat:

Zitat von sirius
Das Result:=false wird nie benutzt. Weil, wenn ein Fehler auftritt, wird erstmal in den Finally-block gesprungen und dann ganz raus und keiner interessiert sich mehr für das Ergebnis von abc.

Warum nicht? Result muss ja nicht zwingend False sein wenn eine Exception auftritt.


Zitat:

Zitat von omata
Vielleicht, weil du die Funktion noch nirgends benutzt?

Die Funktion wird aufgerufen, ob ich habe Result nicht ausgewertet, also mit
Delphi-Quellcode:
Result := abc;
kommt der Hinweis nicht mehr ( :wall: )

API 17. Jan 2009 21:17

Re: Function Result
 
@mr_emre_d: wäre eine Möglichkeit. Doch warum 2 try..except wenn es mit einem nun geht? oder was ist der Vorteil?

mr_emre_d 17. Jan 2009 21:26

Re: Function Result
 
also

der erste try finally block --> nachdem gecreated wurde MUSS es gefreet werden !

und zum zweiten block --> hier findet die exception statt... falls n fehler auftritt,
result = false, sonst, falls es bis zur except zeile kommt (und es natürlich nicht
ausführt) result = true !

:)

Edit:
Obwohl ... es ginge auch, wenn nichts in der except end zeile stehen würde ..

Sir Rufo 18. Jan 2009 00:48

Re: Function Result
 
@API: Dein erster Code ist völlig in Ordnung und der Rückgabewert ist so, wie du ihn haben möchtest.

Aber ... da Du den Resultwert niemals abgefragt hast
Delphi-Quellcode:
begin
  abc;
end;
meckert der Compiler und fragt mal höflich an, warum du eine Funktion definierst, aber den Rückgabewert gar nicht haben willst (dann nimm doch eine procedure!) ;)

Gleiches Verhalten erhältst Du auch mit
Delphi-Quellcode:
var abc : integer;
begin
  abc := 1;
end;
und ist ja auch logisch, da soll der Rechner was machen, ist aber irgendwie für nix gut.

Hintergrund: Im Regelfall geht der Compiler davon aus, wenn ich einer Variablen einen Wert zuweise, dann will ich den ja wohl auch irgendwann mal benutzen. Mache ich das nicht, habe ich das vielleicht ja vergessen zu Benutzen (oder halt überflüssigen Kram programmiert).

cu

Oliver

Hawkeye219 18. Jan 2009 08:53

Re: Function Result
 
Hallo,

in diesem Fall schließe ich mich sirius und seiner Erklärung in Beitrag #2 an. Tritt innerhalb der Funktion eine Exception auf, erfolgt (meistens) über FINALLY ein Sprung zur Fehlerbehandlung und nicht zur Aufrufstelle. Der einzig mögliche Rückgabewert der Funktion kann also im gezeigten Beispiel (bei einem ordnungsgemäßen Ablauf) nur True sein; eine Prozedur würde hier daher vollkommen ausreichen, weil das Funktionsergebnis konstant ist. Nur wenn die im Funktionsrumpf auftretende Exception auch dort abgefangen wird, ist eine Funktion sinnvoll:

Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObjectX;
begin
  Result := False;
  try
    Obj := TObjectX.Create;
    with Obj do
    try
      // ..
      Result := True;
    finally
      Free;
    end;
  except
    on E: ESpezielleException do
      ...
  end;
end;
Bei dieser Vorgehensweise bleibt auch die Meldung des Compilers aus. Ob ein Abfangen der Exception hier sinnvoll ist, und welche Exceptions dafür in Frage kommen, das liegt im Ermessen des Programmierers.

Gruß Hawkeye

mjustin 18. Jan 2009 10:44

Re: Function Result
 
Zitat:

Zitat von Hawkeye219
Bei dieser Vorgehensweise bleibt auch die Meldung des Compilers aus. Ob ein Abfangen der Exception hier sinnvoll ist, und welche Exceptions dafür in Frage kommen, das liegt im Ermessen des Programmierers.

Oder so, damit man in der Exceptionbehandlung auch noch auf das Objekt zugreifen kann:

Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObject;
begin
  Result := False;
  Obj := TObject.Create;
  try
    try
      // etwas das schiefgehen kann ...
      ...
      // hat funktioniert:
      Result := True;
    except
      on E:Exception do
      begin
        // behandeln
        ...
      end;
    end;
  finally
    Obj.Free;
  end;
end;
Es muss eigentlich auch keine spezielle Exception behandelt, man muss nur einen try / except Block haben, damit die Warnung nicht mehr ausgegeben wird.

himitsu 18. Jan 2009 13:44

Re: Function Result
 
@mjustin: dann kannst du das Try-Finally auch gleich mit rausürzen ... bei 'ner Exception geht es doch sowieso nach dem END weiter
Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObject;
begin
  Result := False;
  Obj := TObject.Create;
  try
    // etwas das schiefgehen kann ...
    ...
    // hat funktioniert:
    Result := True;
  except
    // behandeln
  end;
  Obj.Free;
end;

omata 18. Jan 2009 13:49

Re: Function Result
 
Ja, nur jetzt wird Obj bei einer Exeption nicht mehr freigegeben.

himitsu 18. Jan 2009 13:56

Re: Function Result
 
doch, wird es :angel: ... kannst's gern ausprobieren

Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObject;
begin
  Result := False;
  Obj := TObject.Create;
  ShowMessage('Obj := TObject.Create;');
  try
    // etwas das schiefgehen kann ...
    // ...
    Raise Exception.Create('123');

    // hat funktioniert:
    Result := True;
    ShowMessage('Result := True;');
  except
    ShowMessage('except');
  end;
  Obj.Free;
  ShowMessage('Obj.Free;');
end;
Nach einem Try-Except-Block wird "IMMER" weitergearbeitet.
Und selbst wenn da mal so ein großer Fehler auftritt, daß selbst Try-Except ihn nicht behandeln könnte, dann würde auch Try-Finally versagen.

omata 18. Jan 2009 13:58

Re: Function Result
 
Ok, hast recht. Die Exception wird ja behandelt, danach geht es dann normal weiter.

Apollonius 18. Jan 2009 14:01

Re: Function Result
 
Das Finally braucht man allerdings, wenn man einen Exception Filter einbaut. Und das sollte man tun, um System-Exceptions durchzulassen.

mjustin 18. Jan 2009 14:46

Re: Function Result
 
Delphi-Quellcode:
function abc: Boolean;
var
  Obj: TObject;
begin
  Result := False;
  Obj := TObject.Create;
  try
    // etwas das schiefgehen kann ...
    // ...
    // hat funktioniert:
    Result := True;
  except
    begin
      ShowMessage('except und bye bye');
      raise;
    end;
  end;
  Obj.Free; // wird bei Exception nicht mehr erreicht
end;
Wenn man z.B. ein raise im Exceptionhandler hat wie in diesem Beispiel, wird das Objekt beim Auftreten einer Exception nicht mehr freigeben. Daher verwende ich immer das "try .. finally .. Obj.Free .. end" Muster.

himitsu 18. Jan 2009 15:27

Re: Function Result
 
OK, wenn du die Exception duchläßt dann nimmer, aber wenn man die exception abgefangen hat, kann man die doch auch behandeln (selbst wenn es 'ne "System"-xception ist) ... oder wollt ihr den Programmvortlauf durch die Exception steuern/abbrechen lassen? :shock:

Apollonius 18. Jan 2009 15:34

Re: Function Result
 
Solche Schätzchen wie Stack Overflows, Out-Of-Memory-Exceptions o.Ä. lassen sich schwerlich behandeln. Es ist so ziemlich das Dümmste, was man tun kann, solche Exceptions abzufangen und dann ohne Meldung oder mit einer in der Art von "Datei konnte nicht gefunden werden" weiterzulaufen. In den allermeisten Fällen gibt es abgesehen von einem Absturz mit einer aussagekräftigen Meldung einfach nichts zu tun.

mjustin 18. Jan 2009 15:48

Re: Function Result
 
Zitat:

Zitat von himitsu
OK, wenn du die Exception duchläßt dann nimmer, aber wenn man die exception abgefangen hat, kann man die doch auch behandeln (selbst wenn es 'ne "System"-xception ist) ... oder wollt ihr den Programmvortlauf durch die Exception steuern/abbrechen lassen? :shock:

Eine spannende Frage hierbei ist: kann man eigentlich in einer Funktion sowohl eine Exception auslösen, als auch ein Funktionsergebnis zurückliefern, anders gefragt: hat der aufrufende Code überhaupt eine Chance, das Funktionsergebnis zu erhalten, wenn in der Funktion eine Exception geworfen (und nicht behandelt) wird?

Beispiel:

Delphi-Quellcode:
try
  X := ThrowsException(Y);
finally
  // behandle Exception ...
end;

ComputeSomething(X);
Wird der Variable X noch der Funktionswert zugewiesen, der in der Methode ThrowsException (vor einem raise) dem Result zugewiesen wurde, bevor zum finally gesprungen wird? Oder ist der Wert von X beim Aufruf von ComputeSomething undefiniert?

Apollonius 18. Jan 2009 15:59

Re: Function Result
 
Das hängt vom Typen ab. Bei intern als Out-Parametern zurückgegebenen Typen, d.h. Records, Arrays, Interfaces, Strings und Variants, kommt ein gültiges Resultat zustande. Bei allen anderen Typen nicht.

himitsu 18. Jan 2009 16:12

Re: Function Result
 
Das "normale" Result wird bei einer Exception nicht zurückgegeben, da ab dem Fehler nicht zum aufrufenden Punkt zurückgesprungen wird (da wo die Funktion aufgerufen wurde und das Ergebnis entgegengenommen wird) ... bei 'ner exception wird zum vorherigen (beim TRY definierten) Rückkehrpunkt gesprungen.

in Delphi ist das bei Try-Except-End ist das nach dem EXCEPT und danach nach das END
und bei Try-Finally-End wird nach das FINALLY gesprungen und beim END wird die Exception erneut ausgelöst und somit wiederum zum übergeordneten (wenn vorhanden, sonst ist hier die Threadbearbeitung beendet) Try-Finally/Except, bzw. dessen Rückkehrpunktes gesprungen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:59 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