Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Assigned=true bei uninitialisierter Variable ? (https://www.delphipraxis.net/204756-assigned%3Dtrue-bei-uninitialisierter-variable.html)

Int3g3r 25. Jun 2020 17:44

Delphi-Version: 10.1 Berlin

Assigned=true bei uninitialisierter Variable ?
 
Guten Abend,

Delphi-Quellcode:
procedure THeaderFooterForm.FormActivate(Sender: TObject);
var server : TServer;
begin
   //server := nil;
   if not assigned(server) then
      server := TServer.Create('127.0.0.1',25222,true);
      server.StopTCPServer;
      FreeAndNil(server);
end;
Ich verwende hier eine lokale Variable für den TServer.
Wenn ich am Anfang "server := nil;" nicht schreibe ist assigned true und das Create Event wird übersprungen.
Somit erhalte ich eine exception sobald ich auf die Variable zugreife.

Kann mir jemand erklären warum assigned = true ist bei einer lokalen Variable die wie hier zu sehen sonst gar nicht verwendet wird ?

Ich kann mir nur vorstellen das per Zufall an dieser Adresse gerade ein Objekt "ist/vorher war" und daher assigned true zurück gibt, ist dies korrekt ?
Lokale Variablen werden ja nie initialisiert somit haben diese einen undefinierten Wert.
Somit wäre es zwingend notwenig in diesem Fall die Variable zu initialisieren.

Gruss Int3g3r

DeddyH 25. Jun 2020 17:55

AW: Assigned=true bei uninitialisierter Variable ?
 
Assigned heißt ja nichts anderes, als dass die Variable nicht nil ist. Wie Du bereits weißt, sind lokale Variablen nicht initialisiert, da ist die Wahrscheinlichkeit verschwindend gering, dass sie bei ihrer Deklaration eine 0-Entsprechung (also nil) enthält, Assigned gibt also true zurück.

Hobbycoder 25. Jun 2020 18:27

AW: Assigned=true bei uninitialisierter Variable ?
 
Du erzeugst ja lokal nur eine Variable vom Typ TServer. Im Speicher existiert das Object noch gar nicht.
Demnach kannst du dir die Prüfung mit not Assigned an der Stelle schenken. Assigned wird dann immer False bzw. not Assigned immer True liefern. Tut es zumindest bei mir.
Die Assinged-Prüfung macht erst NACH dem Create Sinn. Denn erst dann wird der Speicher reserviert und die Adresse zugewiesen, sofern dabei kein Fehler auftritt.

Zweitens müsste du nach deinem if Assigned() then auch in einem Block weitermachen.

Delphi-Quellcode:
procedure THeaderFooterForm.FormActivate(Sender: TObject);
var server : TServer;
begin
  server := TServer.Create('127.0.0.1',25222,true);
  if assigned(server) then
  begin
    server.StopTCPServer;
    FreeAndNil(server);
  end;
end;
Noch besser wäre so:
Delphi-Quellcode:
procedure THeaderFooterForm.FormActivate(Sender: TObject);
var server : TServer;
begin
  try
    server := TServer.Create('127.0.0.1',25222,true);
    try
      server.StopTCPServer;
    finally
      FreeAndNil(server);
    end;
  except
    ShowMessage('Server konnte nicht gestartet werden.');
  end;
end;
Assigned solltest du verwenden, wenn bestimmte Codeabschnitte nur ausführbar sind, wenn eine Variable<>nil ist. Um Fehler abzufangen: Try..Except

himitsu 25. Jun 2020 19:17

AW: Assigned=true bei uninitialisierter Variable ?
 
Tja, lokale Variablen sind nunmal per se niemals initialisiert (mit einigen Ausnahmen) und sind potentiell mit Zufallswerten gefüllt,
also musst du vorher irgendwas zuweisen, bevor du den Inhalt prüfen oder auslesen willst.

Zufallswerte: einmal 0 oder uber 4 Milliarden Mal was Anderes und die Stochastik lehrt dich, dass du wahrscheinlich meistens keine 0 bekommst. :angle:

Zitat:

Delphi-Quellcode:
var server : TServer;
begin
   //server := nil;
   if not assigned(server) then

Ich hoffe mal der Compiler hat dich korrekt ausgemeckert, dass du auf eine uninitialisierte Variable zugreifst.

Fazit: Du darfst die Zuweisung nicht auskommentieren,
oder lass sie nutzlose vorherige Zuweisung und das IF-Assigned einfach weg (siehe Vorredner) und initialisiere die Variable mit deiner neuen Instanz.



keine Ressourcenschutzblöcke?
Wenn es im StopTCPServer knallt, dann hast du ein wunderschönes Speicherleck.

Heimlich 26. Jun 2020 10:36

AW: Assigned=true bei uninitialisierter Variable ?
 
Zitat:

Zitat von Hobbycoder (Beitrag 1468223)
Noch besser wäre so:
Delphi-Quellcode:
procedure THeaderFooterForm.FormActivate(Sender: TObject);
var server : TServer;
begin
  try
    server := TServer.Create('127.0.0.1',25222,true);
    try
      server.StopTCPServer;
    finally
      FreeAndNil(server);
    end;
  except
    ShowMessage('Server konnte nicht gestartet werden.');
  end;
end;

Was ist, wenn der Fehler in StopTCPServer passiert, dort aber keine Fehlerbehandlung erfolgt?

himitsu 26. Jun 2020 11:30

AW: Assigned=true bei uninitialisierter Variable ?
 
Zitat:

Zitat von Hobbycoder
Noch besser wäre so

Nicht wirklich.

Man vernichtet nicht sinnlos Fehlermeldungen.
Weiterer Text als Zusatzinfo ist OK, aber wenn dann mit der Originalmeldung im Fenster (unten zum Aufklappen oder auf Knopfdruck), oder zumindestens in einem Log.

Heimlich 26. Jun 2020 12:09

AW: Assigned=true bei uninitialisierter Variable ?
 
Zitat:

Zitat von himitsu (Beitrag 1468245)
Zitat:

Zitat von Heimlich (Beitrag 1468244)
Noch besser wäre so

Nicht wirklich.

Man vernichtet nicht sinnlos Fehlermeldungen.
Weiterer Text als Zusatzinfo ist OK, aber wenn dann mit der Originalmeldung im Fenster (unten zum Aufklappen oder auf Knopfdruck), oder zumindestens in einem Log.

Ist mir eigentlich ziemlich wurscht, da Du den Falschen zitiert hast. Das try..except wird einfach falsch verwendet und die Meldung ist auch Fail. Kann richtig sein, muss aber nicht. Die Meldung kann zu Zeitverschwendung bei der Fehlersuche führen.

himitsu 26. Jun 2020 12:13

AW: Assigned=true bei uninitialisierter Variable ?
 
Ups, den falschen gesteinigt.
Dann nehm ich den Felsen erstmal heimlich wieder runter, hat ja niemand gesehn. :stupid:

Zitat:

Zitat von Heimlich
Die Meldung kann zu Zeitverschwendung bei der Fehlersuche führen.

Und jupp, genau deswegen.

Hobbycoder 26. Jun 2020 14:40

AW: Assigned=true bei uninitialisierter Variable ?
 
Zitat:

Zitat von Heimlich (Beitrag 1468247)
Ist mir eigentlich ziemlich wurscht, da Du den Falschen zitiert hast. Das try..except wird einfach falsch verwendet und die Meldung ist auch Fail. Kann richtig sein, muss aber nicht. Die Meldung kann zu Zeitverschwendung bei der Fehlersuche führen.

Die Meldung mit ShowMessage diente mehr der Veranschaulichung. Was ist denn bitte an dem try..except falsch, außer er Tatsache dass man statt der Meldung eine Fehlercode ausgeben könnte? Wie und Welche Fehlermeldung der TE ausgeben will weiß ich doch nicht und könnte er auch selber machen.

Int3g3r 9. Jul 2020 16:20

AW: Assigned=true bei uninitialisierter Variable ?
 
Vielen Dank für alle Kommentare und Klarstellungen.

freimatz 13. Jul 2020 10:17

AW: Assigned=true bei uninitialisierter Variable ?
 
Zitat:

Zitat von DeddyH (Beitrag 1468222)
... Wie Du bereits weißt, sind lokale Variablen nicht initialisiert, da ist die Wahrscheinlichkeit verschwindend gering, dass sie bei ihrer Deklaration eine 0-Entsprechung (also nil) enthält, ...

Verschwindend würde ich jetzt nicht behaupten. Nach meiner Erfahrung kommen Nullen auf dem Stack häufiger vor als andere Werte. Da muss nur eine Methode zuvor an der gleiche Stelle eine da dann mit nil initialisierte Referenz haben.
Es ist zwar immer noch gering - Nur dass jemand auf die Idee kommt, er könne sich bei "verschwindend gering" darauf verlassen ;-)


Alle Zeitangaben in WEZ +2. Es ist jetzt 16:12 Uhr.

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