AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Übergebenes nil erkennen?

Ein Thema von solus · begonnen am 25. Apr 2012 · letzter Beitrag vom 30. Apr 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.505 Beiträge
 
Delphi 12 Athens
 
#1

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 08:53
Wobei Delphi auch hart typsicher unterscheidet.

Du kannst einen Pointer nicht auf 0 setzen oder einen Integer auf nil.
Für den Variant gibt es den Wert NULL (auch als Konstante) und wenn man dem Variant eine 0 zuweist, dann ist was was Anders.

Daß intern, also die Daten im RAM, der Integer (eigentlich aber richtiger Cardinal) NativeUInt den selben Wert aufweisen, das ist soweit richtig.
Dennnoch
Delphi-Quellcode:
nil <> 0
Cardinal(nil) = 0 // nur für 32 Bit, da ein paar Idioten meinten Integer/Cardinal einfrieren zu müssen
NativeUInt(nil) = 0
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 10:26
Stimmt, ohne Casts ist Delphi an sich da auch "sauber". Gar nicht mehr im Hinterstübchen gehabt =) Ebenso die Variants - viel zu selten Benutzt bei mir, aber ich erinnere mich: Das müsste das OLE_NULL sein gell? Dann ist bei denen sogar wie in Datenbanken die Unterscheidung von NULL und 0 noch deutlicher und nicht so einfach via Cast überführbar. Danke fürs zurechtrücken!

Für die Initialisierung von Feldern gilt aber dennoch, weil FillChar da ja ohne Typprüfung drüberjodelt, initialisiert mit 0 -> Referenzen gelten als nil.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (26. Apr 2012 um 10:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.505 Beiträge
 
Delphi 12 Athens
 
#3

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 10:59
Wurde z.B. in einem Record etwas eingetragen und du willst es dennoch "sicher" nullen, dann

Delphi-Quellcode:
var
  R: record
    ..
  end;

Finalize(R);
FillChar(R, SizeOf(R), 0);
Alternativ kann man etwas manuell initialisieren, wenn es von Delphi noch nicht automatisch initialisiert wurde
Delphi-Referenz durchsuchenInitialize
Delphi-Referenz durchsuchenFinalize
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.051 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 17:44
Schonmal aufgefallen, dass ne AV mit der Meldung "Read of address 00000000'." in den meisten Fällen auf einen nil Pointer hinweist?
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
solus

Registriert seit: 25. Apr 2012
7 Beiträge
 
#5

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 19:49
Whoa, was sich doch nicht alles aus einer einfachen Frage ergibt.

Der konkrete Anwendungsfall (über das Minimalbeispiel hinaus) war die Erstellung eines Binären Suchbaums (AVL).

type TKnoten=class(TObject)

rechts,links : TKnoten
...
end;

function hoehe(knoten:TKnoten) : integer;
begin
if knoten =nil then result:=0
else ...
end;

function balance(knoten : TKnoten) : integer;
begin
result:=hoehe(links)-hoehe(rechts);
end;

Das Warnsystem hat bei mir daher nicht angeschlagen (rechts,links werden ja benutzt) und Objektfelder werden anscheinend wie lokale Variablen behandelt.

Mittels

constructor create; override;
begin
inherited create;
rechts:=nil;
links:=nil;
end;

sollte ich dann aber sicher sein, oder?

Einzige Alternative wäre halt ne blöde Fallunterscheidung...
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 20:41
Hast du bei deinen Methoden einfach nur das "TKnoten." vergessen, oder sind das wirklich nur Funktionen/Prozeduren (gegenüber Methoden (welche immer zu einer Klasse gehören))? In dem Fall würden die Felder nicht wie lokale Variablen behandelt, sondern Delphi setzt innerhalb von Methoden der Klasse vor die eigenen Felder implizit eine "self." Referenz. Es sind aber nach wie vor Felder, keine lokalen Variablen. Es muss daher, dem Beispiel hier nach, auch ohne explizites nil im Konstruktor gehen (welche man übrigend nicht überläd).

Ich vermute schon fast einen Klassiker hier:
Delphi-Quellcode:
var
  k: TKnoten;
begin
  // Erzeugung vergessen
  k.TuWas();
  .
  .
end;
Also Fehler in der Verwendung, nicht der Klasse selbst. Gegebenenfalls kann das auch innerhalb einer Methode von TKnoten passieren, wenn es dort solche gibt, die neue Knoten einfügen und diese selbst erzeugen müssten (also keinen fertigen neuen TKnoten als Parameter von aussen mit bekommen).
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (26. Apr 2012 um 20:43 Uhr)
  Mit Zitat antworten Zitat
solus

Registriert seit: 25. Apr 2012
7 Beiträge
 
#7

AW: Übergebenes nil erkennen?

  Alt 26. Apr 2012, 20:55
Es geht doch gerade darum, dass nicht initialisiert wird.

Ich habe einen Baum und will die Höhe des rechten Unterbaums der Wurzel wissen und rufe daher

hoehe(wurzel.rechts) auf (jaja unsauber, rechts sollt private sein)

dummerweise ist der rechte Unterbaum leer. Da ich aber im constructor wurzel.rechts:=nil gesetzt habe, rufe ich effektiv hoehe(nil) auf und bekomme 0 zurück.

Geht das?

(PS: Ich hab den Konstruktor dich nicht überladen, sondern überschrieben, oder?)
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Übergebenes nil erkennen?

  Alt 27. Apr 2012, 10:04
Delphi-Quellcode:
constructor TKnoten.Create; override;
begin
  inherited Create;
  rechts:=nil;
  links:=nil;
end;
Sollte ich dann aber sicher sein, oder?
Ich würde es genau so machen.
Das meinte ich eigentlich mit "Trau nicht dem Compiler".
In dem Fall, dass Du Dir nicht sicher bist, ob die Variablen "richtig" initialisiert werden, solltest Du sie einfach selbst initialisieren.
Dann bist Du auf der sicheren Seite.

Ich empfinde es auch als "Dokumentation" gut, wenn Variablen initialisert werden, und man sich nicht darauf verlässt, das es der Compiler schon richtig initalisieren wird. Das zeigt dass Du bewusst diesen Wert (in Deinem Fall nil) zugewiesen haben möchtest.

Das ist wie beim Rechnen. Auch wenn eindeutig geregelt ist, macht es manchmal Sinn eine Klammer zu setzen.
2*2+2*2 = (2*2)+(2*2)
Wenn jemand in den Taschenrechner 2*2+2*2 eingibt macht er (2*2+2)*2
Das sollte jeder wissen, aber mit Klammern ist es eindeutig zu sehen.

Nichts anderes wollte ich oben mit meinem Beitrag ausdrücken.
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.051 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#9

AW: Übergebenes nil erkennen?

  Alt 29. Apr 2012, 02:16
Ich empfinde es auch als "Dokumentation" gut, wenn Variablen initialisert werden, und man sich nicht darauf verlässt, das es der Compiler schon richtig initalisieren wird. Das zeigt dass Du bewusst diesen Wert (in Deinem Fall nil) zugewiesen haben möchtest.
Dem muss ich widersprechen.

Für mich persönlich ist es sehr viel verwirrender, wenn ich sowas im Sourcecode sehe. Dann frag ich mich, ob hier entweder ein ahnungsloser am Werke war, oder ob es irgendein Problem gab, weswegen das gemacht wurde.

Genauso initialisier ich eine Variable nur dann, wenn deren Wert irgendwo benutzt wird, bevor ihr ein Ergebnis einer Operation zugewiesen wird. (Stichwort H2077 Value assigned to <variable> never used)
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz