Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktion ohne Result? (https://www.delphipraxis.net/32010-funktion-ohne-result.html)

fkerber 17. Okt 2004 11:13


Funktion ohne Result?
 
Hi!

Ich habe folgende Funktion:

Delphi-Quellcode:
function DeleteUser(user: String): Boolean;
var
 Identities: TIniFile;
begin
 result:=False;         // <--------
 Identities:=TIniFile.Create(ExtractFilePath(paramstr(0))+'\Identities.dat');
 Try
   Identities.EraseSection(user);
   Result:=True;
 Finally
   Identities.Free;
 end;
end;
Die markierte Zeile wird manchmal nicht mitkompiliert (dieser blaue Punkt am Rand fehlt) oder es kommt dann ein Hint im Sinne von ("Der Wert DeleteUser wird nie benutzt").
Ich rufe die Funktion in einer If-Abfrage auf. Wenn jetzt also der Zugriff auf die Ini fehlschlägt dann sollte das Result eigentlich False sein. Nur wie soll das sein, wenn die Zeile gar nicht mitkompiliert wird?
Ich kann die Zeile auch rauslöschen. Da hätte ich jetzt eher ne Warnung wie "Funktionsresult könnte undefiniert sein" erwartet.

Habe ich irgendwo nen Denkfehler?

Ciao Frederic

himitsu 17. Okt 2004 11:33

Re: Funktion ohne Result?
 
Also eigentlich denkst du richtig ... denke ich mal :gruebel:


Du könnest ja auch andersrum versuchen - mit Except, das sollte auch gehn:
Delphi-Quellcode:
function DeleteUser(user: String): Boolean;
var
Identities: TIniFile;
begin
Result:=True;
Identities:=TIniFile.Create(ExtractFilePath(paramstr(0))+'\Identities.dat');
Try
   Identities.EraseSection(user);
Except
   Result:=False;        
end;
Identities.Free;
end;
Man könnte auch mal die Code-Optimierung (teilweise) abstellen:
Delphi-Quellcode:
...
begin
{$O-} Result:=False; {$O+}
Identities:=TIniFile.Create(ExtractFilePath(paramstr(0))+'\Identities.dat');
...

fkerber 17. Okt 2004 11:35

Re: Funktion ohne Result?
 
Hi!

Ja, das geht sicherlich auch, aber es interessiert mich in erster Linie auch, warum das so passiert. Im Prinzip macht der Compiler da ja nen Fehler rein, oder?

Ciao Frederic

himitsu 17. Okt 2004 11:47

Re: Funktion ohne Result?
 
Ich denk mal, es ist ein Fehler in der Code-Optimierung ... so wie es aussieht geht die davon aus, das alles zwischen Try und Finally ausgeführt wird.

- Wenn ich Result:=True; (in Try/Finally) wegnehme, dann wird das Result:=False; ja mitkompiliert.

fkerber 17. Okt 2004 11:49

Re: Funktion ohne Result?
 
Hi!

Ja, aber er kann ja nicht davon ausgehen, dass derTry erfolgreich ausgeführt wird, oder?
Was passiert, wenn nicht?

Ciao Frederic

SirThornberry 17. Okt 2004 11:52

Re: Funktion ohne Result?
 
Ist eindeutig ein Fehler in der Codeoptimierung, den bei Try-Except functionierts ja (zumindest als ich das benutzt hab)

himitsu 17. Okt 2004 12:00

Re: Funktion ohne Result?
 
Na dann scheuchen wir mal die Daniels auf ... die haben doch so gute Beziehungen zu Borland ... dann sollte der Fehler ja bis nächste Woche behoben sein :roll:

Christian Seehase 17. Okt 2004 12:01

Re: Funktion ohne Result?
 
Moin Frederic,

Zitat:

Zitat von fkerber
Im Prinzip macht der Compiler da ja nen Fehler rein, oder?

eigentlich nicht.

Der Try-Abschnitt wird, bei normalem Programmablauf, immer durchlaufen, und somit Result dort gesetzt.
Es spielt hierbei auch keine Rolle, ob es sich nun um einen Try/Finally oder einen Try/Except Block handelt.

Da Result nur im Fehlerfalle auf false stehen soll, müsstest Du es so machen, wie Himitsu es vorgeschlagen hat.
Ich würde hier allerdings auch noch einen try/finally Block ergänzen, damit auch im Falle eines Fehlers das Inifile-Objekt wieder freigegeben wird.

Delphi-Quellcode:
function DeleteUser(user: String): Boolean;

var
  Identities: TIniFile;

begin
  Result:=True;
  Identities:=TIniFile.Create(ExtractFilePath(paramstr(0))+'\Identities.dat');
  try
    Try
      Identities.EraseSection(user);
    Except
      Result:=False;        
    end;
  finally
    Identities.Free;
  end;
end;

fkerber 17. Okt 2004 12:01

Re: Funktion ohne Result?
 
Hi!

Das ist dann schlecht :roll:
Dann muss ich wohl umbauen.

ciao Frederic

Christian Seehase 17. Okt 2004 12:03

Re: Funktion ohne Result?
 
Moin Sir Thornberry,

Zitat:

Zitat von SirThornberry
Ist eindeutig ein Fehler in der Codeoptimierung, den bei Try-Except functionierts ja (zumindest als ich das benutzt hab)

So?
Dann setz' mal die Zeile in den Try-Abschitt des Try/Except-Blocks ;-)

fkerber 17. Okt 2004 12:03

Re: Funktion ohne Result?
 
Hi!

@Sakura:
Ich dachte der Try-Block wird verlassen, wenn das Erase fehlschlägt. Ist das nicht der Fall?

Ciao Frederic

himitsu 17. Okt 2004 12:08

Re: Funktion ohne Result?
 
Zitat:

Zitat von fkerber
Hi!

@Sakura:
Ich dachte der Try-Block wird verlassen, wenn das Erase fehlschlägt. Ist das nicht der Fall?

Ciao Frederic

Also bei mir macht das Programm das jedenfalls auch immer so :gruebel:


PS:
Zitat:

[Warnung] ...(...): Rückgabewert der Funktion 'DeleteUser' könnte undefiniert sein
kommt natürlich nicht, wenn man das obere Result ganz wegläßt.


PS2:
Na ja, es ist auch 'ne schwirige Entscheidung, wann es überflüßig ist/ausgeführt wird, oder nicht...

Delphi-Quellcode:
Try
   Result:=False;        // das wird wohl "immer" ausgeführt (egal ob ein Fehler passiert, oder nicht)
   {mach was Kritisches}
Finally
   ...
end;
Delphi-Quellcode:
Try
   {mach was Kritisches}
   Result:=False;        // hier sieht das ja aunders aus.
Finally
   ...
end;

SirThornberry 17. Okt 2004 12:19

Re: Funktion ohne Result?
 
Warum eigentlich nicht einfach so?
Delphi-Quellcode:
function DeleteUser(user: String): Boolean;
var Identities: TIniFile;
begin
  try
    Identities:=TIniFile.Create(ExtractFilePath(paramstr(0))+'\Identities.dat');
    try
      Identities.EraseSection(user);
      result := True;
    except
      result := False;
    end;
    Identities.Free;
  except
    result := False;
  end;
end;
da wird das Identities.Free auch immer ausgeführt wenn das TIniFile.Create erfolgreich ist, und wenn nicht wird das result auf False gesetzt, wobei man den äußeren Try-Exceptblock weglassen könnte da TIniFile.Create nie schief geht außer der Speicher ist voll.

fkerber 17. Okt 2004 12:24

Re: Funktion ohne Result?
 
Hi!

Wozu dient der äußerste Try-Block?

Ciao Frederic

Christian Seehase 17. Okt 2004 12:25

Re: Funktion ohne Result?
 
Moin Zusammen,

noch einmal anderes forumliert:

Try/Finally wird auch als Resourcenschutzblock bezeichnet.
Er dient dazu sicherzustellen, das belegte Resourcen, auch im Falle eines Fehlers, wieder freigegeben werden.

Try/Except dient hingegen dazu die Kontrolle über die Steuerung zu behalten falls ein Fehler auftritt, so dass man eben, wie es hier sein soll, einen entsprechenden Return Code setzen, und ansonsten die Exception unterdrücken kann.

Genau durch die Verwendung dieser Blöcke teilt man dem Compiler ja mit, wo er für eventuelle Fehler zusätzlichen Code generieren soll.
Inwiefern etwas kritisch für die Programmlogik ist, wird der Compiler nicht entscheiden können.

Der Hinweis, dass die Initialisierungszeile nicht mit übersetzt wird kann dann schon einen Hinweis darauf geben, dass man etwas geschrieben hat, dass nicht so läuft wie gedacht.

Christian Seehase 17. Okt 2004 12:28

Re: Funktion ohne Result?
 
Moin Sir Thornberry,

Zitat:

Zitat von SirThornberry
da wird das Identities.Free auch immer ausgeführt wenn das TIniFile.Create erfolgreich ist,

Nein, wird es nicht.
Wenn EraseSection eine Exception auslöst wird zweimal hintereinander Result auf false gesetzt, und die Prozedur verlassen, ohne die Identities.Free Zeile auszuführen.

fkerber 17. Okt 2004 12:36

Re: Funktion ohne Result?
 
Hi!

Ok, dann baue ich da mal um.
Danke.

Ciao Frederic


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