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/)
-   -   Übergebenes nil erkennen? (https://www.delphipraxis.net/167926-uebergebenes-nil-erkennen.html)

solus 25. Apr 2012 18:54

Delphi-Version: 6

Übergebenes nil erkennen?
 
Guten Tag,

ich möchte einer Funktion eine Objektreferenz übergeben, die evtl. nil ist.
Die Funktion soll dann erkennen, ob ein nil übergeben wurde und entsprechend (nicht) reagieren.

Bisher dachte ich, dass Objektvariablen immer auf nil initialisert werden, wie integers immer auf 0 initialisiert werden.

Führe ich aber folgenden Code aus:

Delphi-Quellcode:
var blub : TRandomObject;
begin
if blub=nil then showmessage('1');
tim:=nil;
if blub=nil then showmessage('2');
end;
erscheint nur eine '2'.

Experimente mit assigned(blub) haben auch nicht weitergeholfen.

Mache ich etwas falsch oder muss ich die Objektvariablen manuell auf nil setzen?

Vielen Dank, Viele Grüße,
Solus

DeddyH 25. Apr 2012 18:57

AW: Übergebenes nil erkennen?
 
Lokale Variablen werden normalerweise nicht initialisiert, Du wirst daher den Pointer händisch auf nil setzen müssen.

[edit] Sry, Willkommen in der DP :dp: [/edit]

solus 25. Apr 2012 19:53

AW: Übergebenes nil erkennen?
 
Vielen Dank für die Antwort.

Im eigentlichen Anwendungsfall lag keine lokale Variable sondern ein Feld eines Objekts vor.
Gilt hier dasselbe und sollten die Variablen demnach vom Konstruktor wenn benötigt auf nil gestzt werden?

Analoge Frage: Werden globale Variablen initialisert?

grüße,
solus

MaBuSE 25. Apr 2012 21:27

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von solus (Beitrag 1163553)
Im eigentlichen Anwendungsfall lag keine lokale Variable sondern ein Feld eines Objekts vor.
Gilt hier dasselbe und sollten die Variablen demnach vom Konstruktor wenn benötigt auf nil gestzt werden?

Grundsätzlich sollte ein Programmierer nie dem Compiler vertrauen und alle Variablen initialisieren.

Der Compiler gibt auch Warnungen beim Compilieren aus.
-> http://www.delphi-treff.de/tutorials...wirds-wichtig/

Versuche grundsätzlich Deine Anwendung so zu schreiben, dass keine Warnungen und Hinweise auftreten.

Ausnahme: Warnungen die Du selbst einbaust
Delphi-Quellcode:
{$message warn 'Hier muss ich noch mal genau prüfen !!!'}
oder
Delphi-Quellcode:
{$message hint 'TODO: Quellcode muss noch kommentiert werden, damit es auch ein anderer versteht ;)'}
.
Wenn Du Deinen Code immer sauber hällst, fallen solche eigenen Hinweise und Warnungen natürlich auf und animieren Dich das angemahnte auch zu tun.

Zitat:

Zitat von solus (Beitrag 1163553)
Analoge Frage: Werden globale Variablen initialisert?

Ja, wenn man sie z.B. so definiert:
Delphi-Quellcode:
...
var
  s: string = 'DefaultWert';
  i: Integer = 0;
...

himitsu 25. Apr 2012 22:01

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von DeddyH (Beitrag 1163550)
Lokale Variablen werden normalerweise nicht initialisiert, Du wirst daher den Pointer händisch auf nil setzen müssen.

Wobei der Compiler dafür eigentlich auch eine Warnung werfen sollte, so ala "Variable nicht initialisiert", aber das wurde glaub ich schon erwähnt. :angle2:
Genauso wird auch erwähnt, wenn man Variablen setzt und ihre Werte nirgends verwendet.

Globale Variablen und Felder in Objekten werden immer mit 0 initialisiert (also auch nil und Leerstrings '').
Aber bei lokalen Variablen werden nur bestimmte Typen automatisch initialisiert. Nur jene, welche automatisch von Delphi verwaltet werden. (Strings, dynamische Arrays und Interfaces)

Zitat:

Ja, wenn man sie z.B. so definiert:
Nein, diese werden immer initialisiert.
Nur kann man einen alternativen Initialwert vorgeben.

MaBuSE 25. Apr 2012 22:04

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von himitsu (Beitrag 1163562)
Wobei der Compiler dafür eigentlich auch eine Warnung werfen sollte, so ala "Variable nicht initialisiert". :angle2:

Ich war schneller :tongue:

Zitat:

Zitat von MaBuSE (Beitrag 1163558)
Der Compiler gibt auch Warnungen beim Compilieren aus.
-> http://www.delphi-treff.de/tutorials...wirds-wichtig/


Stevie 25. Apr 2012 22:15

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1163558)
Grundsätzlich sollte ein Programmierer nie dem Compiler vertrauen und alle Variablen initialisieren.

Ich frag mich gerade, ob du selber deinen Bytecode schreibst, wenn du das nicht tust. Dass Felder initialisiert werden, ist dokumentiertes Verhalten. Ordinalwerte sind 0, Boolean ist False, Zeiger sind nil, Strings sind leer.

himitsu 26. Apr 2012 00:00

AW: Übergebenes nil erkennen?
 
Nja, war'n bissl langsamer beim Lesen. :oops:

MaBuSE 26. Apr 2012 00:04

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von Stevie (Beitrag 1163564)
Zitat:

Zitat von MaBuSE (Beitrag 1163558)
Grundsätzlich sollte ein Programmierer nie dem Compiler vertrauen und alle Variablen initialisieren.

Ich frag mich gerade, ob du selber deinen Bytecode schreibst, wenn du das nicht tust. Dass Felder initialisiert werden, ist dokumentiertes Verhalten. Ordinalwerte sind 0, Boolean ist False, Zeiger sind nil, Strings sind leer.

Wenn es dokumentiert ist, ist das was anderes.
Meines Wissens ist es nur für Strings doumentiert.

[edit]Undokumentiere Dinge, die man "nur" durch ausprobieren weiss, können sich ja jederzeit bei einem Versionswechsel ändern.[/edit]

Wo steht das denn in der Doku?

MaBuSE 26. Apr 2012 00:09

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1163577)
Wo steht das denn in der Doku?

Ich habs gerade gefunden:
In der Delphi Hilfe steht ( http://docwiki.embarcadero.com/RADStudio/XE2/de/Variablen )
Lokale Variablen können nicht in ihren Deklarationen initialisiert werden. Aufeinander folgende Variablendeklarationen (z. B. var X, Y, Z: Real;) dürfen weder Initialisierungen enthalten noch Deklarationen von Varianten und Dateitypen.

Wenn Sie eine globale Variable nicht explizit initialisieren, wird sie vom Compiler mit 0 initialisiert. Objektinstanzdaten (Felder) werden auch mit 0 initialisiert. Auf der Wiin32-Plattform ist der Inhalt von lokalen Variablen so lange undefiniert, bis ein Wert zugewiesen wird.

Der bei der Deklaration einer Variablen zugewiesene Speicher wird automatisch freigegeben, wenn die Variable nicht mehr benötigt wird. Lokale Variablen werden freigegeben, wenn die Prozedur oder Funktion beendet wird, in der sie deklariert sind. Weitere Informationen über Variablen und die Verwaltung des Speichers finden Sie unter Speicherverwaltung.

Wobei 0 <> nil um die Frage vom Threadersteller zu beantworten.

sx2008 26. Apr 2012 00:12

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1163577)
Wo steht das denn in der Doku?

Etwas versteckt, hier:
http://docwiki.embarcadero.com/Libra...t.InitInstance
Setzt alle Speicherzellen in dem für ein neues Objekt reservierten Bereich auf Null und initialisiert den Zeiger auf die Tabelle der virtuellen Methoden der Instanz.

himitsu 26. Apr 2012 00:33

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1163577)
Wenn es dokumentiert ist, ist das was anderes.
Meines Wissens ist es nur für Strings doumentiert.

[edit]Undokumentiere Dinge, die man "nur" durch ausprobieren weiss, können sich ja jederzeit bei einem Versionswechsel ändern.[/edit]

Wo steht das denn in der Doku?

Windows initialisiert Speicher mit 0, wenn man den bei ihm reserviert, somit sind die globalen Variablen auch initialisiert.
Und beim Erstellen von Objekten wird definitiv ein Delphi-Referenz durchsuchenFillChar mit 0 über den Instanzspeicher gejagt.
Zitat:

Zitat von MSDN: VirtualAlloc
Reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

Zitat:

Zitat von OH: TObject.InitInstance
Setzt alle Speicherzellen in dem für ein neues Objekt reservierten Bereich auf Null und initialisiert den Zeiger auf die Tabelle der virtuellen Methoden der Instanz.

Und ansonsten werden auch Strings (ausgenommen der ShortString), dynamische Arrays, Interfaces und Variants immer initialisiert.
Das gilt aber nur die Variablen selber und nicht den Inhalt der Arrays oder Strings ... diese sind wie lokale Variablen, also uninitialisiert, bis auf die genannten Sonderfälle.

Bummi 26. Apr 2012 06:09

AW: Übergebenes nil erkennen?
 
@Mabuse
Delphi-Quellcode:
var
 T:Tbutton;
begin
  t := nil;
  Showmessage(IntToHex(Integer(t),8));
end;

Medium 26. Apr 2012 08:06

AW: Übergebenes nil erkennen?
 
0 <> nil (bzw. NULL) gilt nur semantisch, und ist meist in Datenbanken auch so umgesetzt, wie auch in einigen wenigen Sprachen. In Delphi (und auch C) wird für die Darstellung von nil/NULL der numerische Wert 0 genommen, da er wenn dereferenziert in ungültigen Speicher zeigt, und somit niemals für eine gültige Referenz stehen kann (zumindest in Sprachen, in denen Referenz = Zeiger auf Speicher ist). Theoretisch ist also tatsächlich 0 <> nil, aus praktischen Gründen gilt in Delphi aber doch 0 = nil.

himitsu 26. Apr 2012 08:53

AW: Übergebenes nil erkennen?
 
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

Medium 26. Apr 2012 10:26

AW: Übergebenes nil erkennen?
 
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.

himitsu 26. Apr 2012 10:59

AW: Übergebenes nil erkennen?
 
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

Stevie 26. Apr 2012 17:44

AW: Übergebenes nil erkennen?
 
Schonmal aufgefallen, dass ne AV mit der Meldung "Read of address 00000000'." in den meisten Fällen auf einen nil Pointer hinweist?

solus 26. Apr 2012 19:49

AW: Übergebenes nil erkennen?
 
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...

Medium 26. Apr 2012 20:41

AW: Übergebenes nil erkennen?
 
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).

solus 26. Apr 2012 20:55

AW: Übergebenes nil erkennen?
 
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?)

Medium 26. Apr 2012 21:20

AW: Übergebenes nil erkennen?
 
Ups, ja hast du. Tut man aber genausowenig ;)

Ist der rechte Teilbaum denn gewollt leer, oder ist das Teil des Problems?

solus 26. Apr 2012 21:24

AW: Übergebenes nil erkennen?
 
Darum geht es doch!

In einem Baum kann doch der rechte Unterbaum einfach leer sein. Der Pointer ist trotzdem da, da dort ja ein Unterbaum sein könnte.

Medium 26. Apr 2012 21:27

AW: Übergebenes nil erkennen?
 
Der müsste aber leider wirklich von Anfang an nil sein, ohne dass man es selbst im Konstruktor setzt :gruebel:. Kannst du evtl. ein Testprojekt hier anhängen, dass das illustriert? Weil mir kam es in all den Jahren nicht vor, dass Delphi (in diversen Versionen) da einfach was vergessen hätte. Kann ich dann zwar erst morgen durch Delphi jagen, aber das wäre doch sehr hilfreich jetzt.

Stevie 26. Apr 2012 21:30

AW: Übergebenes nil erkennen?
 
Ich würde auch empfehlen, wenn schon, dann korrekten Source zu posten, und keinen erdachten, der eh nicht funktioniert, so wie dieser hier.

Delphi-Quellcode:
function balance(knoten : TKnoten) : integer;
begin
result:=hoehe(links)-hoehe(rechts);
end;
Sonst können wir nur unsere :glaskugel: befragen, und da ist grad die Batterie leer ;)

solus 26. Apr 2012 21:32

AW: Übergebenes nil erkennen?
 
Ich kann morgen das mal hochladen.

Da ich aber eine Klausur schreibe, ist folgendes momentan für mich wichtiger:

Wenn ich es (evtl. unnötigerweise) setze, wird es sicher als nil erkannt?

Medium 26. Apr 2012 21:34

AW: Übergebenes nil erkennen?
 
Probier es aus. Es sollte an sich problemlos sein, das sollte es aber auch schon ohne. Daher vermute ich da Schnitzer an völlig anderen, möglicherweise sogar ganz unbeteiligten Stellen, weswegen das gesamte Projekt prima wär :)

Stevie 26. Apr 2012 21:35

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von solus (Beitrag 1163739)
Wenn ich es (evtl. unnötigerweise) setze, wird es sicher als nil erkannt?

Gegenfrage: Wenn ich ne Integer Variable auf 5 setze, steht dann hinterher 5 drin? :)

Antwort: ja

solus 26. Apr 2012 21:40

AW: Übergebenes nil erkennen?
 
Ok, gut, Danke für die Antworten.

MaBuSE 27. Apr 2012 10:04

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von solus (Beitrag 1163709)
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.

Stevie 29. Apr 2012 02:16

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1163807)
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)

Furtbichler 29. Apr 2012 06:43

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von Stevie (Beitrag 1164108)
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.

Beide Gedanken könntest Du dir abgewöhnen (und solltet Du vielleicht auch), denn nur weil der Code nicht deinem Geschmack entspricht, heißt das nicht, das ein Ahnungloser ab Werk war oder es ein Problem gab. Das ist so, als ob ein impressionistischer Künstler einem Expressionisten jegliche (handwerkliche) Fähigkeit abspricht. Etwas eng gefasst, die Sichtweise, wenn Du mich fragst.

Code soll selbstdokumentierend sein. Wenn Du eine Initialisierung nur für bestimmte Werte nicht vornimmst, dann musst Du das dem Leser erklären ("Im Falle von 0 macht das Delphi von ganz alleine"). Das wäre dann kein 'selbstdokumentierender' Code, sondern Code für Insider. Nicht gut, zumindest aus Sicht des Clean Code.

Ich muss allerdings zugeben, das hier für den Praktier ein Widerspruch zum "vermeide redundanten Code" oder einfach nur "quatsch nicht soviel" besteht.

Zitat:

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)
Wer würde das nicht tun?

Stevie 29. Apr 2012 11:52

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von Furtbichler (Beitrag 1164113)
Zitat:

Zitat von Stevie (Beitrag 1164108)
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.

Beide Gedanken könntest Du dir abgewöhnen (und solltet Du vielleicht auch), denn nur weil der Code nicht deinem Geschmack entspricht, heißt das nicht, das ein Ahnungloser ab Werk war oder es ein Problem gab. Das ist so, als ob ein impressionistischer Künstler einem Expressionisten jegliche (handwerkliche) Fähigkeit abspricht. Etwas eng gefasst, die Sichtweise, wenn Du mich fragst.

Wir reden hier eigentlich nicht von künstlerischer Freiheit.

In allen objektorientierten Sprachen, mit denen ich bisher gearbeite habe (eventuell ist es aber auch zu lang her, zuletzt nur mit Delphi und C#, also korrigier mich, wenn ich falsch liege) war es so, dass Felder von Objekten immer den Default Wert hatten und man nicht Explizit auf false, Leerstring, nil/null oder 0 setzen musste. Das ist auch eins der ersten Dinge, die ich einem Neuling sage, wenn er mit OOP anfängt. Daher ist überflüssiger Code keine Dokumentation für mich, sondern Code Bloat.


Zitat:

Zitat von Furtbichler (Beitrag 1164113)
Zitat:

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)
Wer würde das nicht tun?

Ich hab nicht gezählt, wie viele Warnings und Hints (unter anderem der besagte) wir in unserem Source im letzten Jahr beseitigt haben, weil sich da scheinbar einige nicht dran gehalten haben in der Vergangenheit. ;)

MaBuSE 30. Apr 2012 10:52

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von Stevie (Beitrag 1164108)
Zitat:

Zitat von MaBuSE (Beitrag 1163807)
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)

Ich finde es schade, dass Du meine Aussagen nicht in den Kontext meiner Aussagen weiter oben in diesem Thread setzt.
(Das finde ich verwirrend :?)

Ich schrieb weiter oben:
Zitat:

Zitat von MaBuSE (Beitrag 1163558)
Grundsätzlich sollte ein Programmierer nie dem Compiler vertrauen und alle Variablen initialisieren.

Der Compiler gibt auch Warnungen beim Compilieren aus.
-> http://www.delphi-treff.de/tutorials...wirds-wichtig/

Versuche grundsätzlich Deine Anwendung so zu schreiben, dass keine Warnungen und Hinweise auftreten.

Ausnahme: Warnungen die Du selbst einbaust
Delphi-Quellcode:
{$message warn 'Hier muss ich noch mal genau prüfen !!!'}
oder
Delphi-Quellcode:
{$message hint 'TODO: Quellcode muss noch kommentiert werden, damit es auch ein anderer versteht ;)'}
.
Wenn Du Deinen Code immer sauber hällst, fallen solche eigenen Hinweise und Warnungen natürlich auf und animieren Dich das angemahnte auch zu tun.

Ich sagte es macht Sinn alle Variablen zu initialisieren, ich sagte nicht, man solle sie mehrfach initialisieren !!!

Delphi-Quellcode:
var
  i: Integer;
begin
  i := 0; // <- Das ist in diesem Falle Blödsinn
  // mach was ohne auf i zuzugreifen ...
  i := FunctionX(...); // <- das ist die initalisierung !!!
  if i = 0 then //...
  //...
end.
Lokale Variablen sind NICHT automatisch initialisiert (außer strings) !!! -> also sollte man das tun.
Bei globelen Variablen kannst Du ja folgendes (zur Dokumentation) verwenden:
Delphi-Quellcode:
var
  i: Integer = 0;
Ich empfinde das nicht als Werk eines Ahnungslosen, sondern als Dokumentation.
Abgesehen davon, dass man globale Variablen eh vermeiden sollte, muß sichergestellt werden, dass diese einen sinnvollen vordefinierten Wert haben.
Auch wenn wir wissen, dass es mit 0 initialisiert wird, sollte es für die, die es nicht wissen dokumentiert sein.

und ein
Delphi-Quellcode:
var i: Integer = 0;
ist kürzer als ein
Delphi-Quellcode:
var i: Integer; // ist mit 0 initialisert
;-)

Stevie 30. Apr 2012 11:43

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von MaBuSE (Beitrag 1164242)
Ich finde es schade, dass Du meine Aussagen nicht in den Kontext meiner Aussagen weiter oben in diesem Thread setzt.
(Das finde ich verwirrend :?)

Es ging um das "ich schreib es lieber hin, weil ich nicht darauf vertraue, dass der Speicher initialisiert ist".

MaBuSE 30. Apr 2012 12:16

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von Stevie (Beitrag 1164251)
Zitat:

Zitat von MaBuSE (Beitrag 1164242)
Ich finde es schade, dass Du meine Aussagen nicht in den Kontext meiner Aussagen weiter oben in diesem Thread setzt.
(Das finde ich verwirrend :?)

Es ging um das "ich schreib es lieber hin, weil ich nicht darauf vertraue, dass der Speicher initialisiert ist".

Ja, aber ein Satz weiter steht doch, dass ein Programm KEINE Hinweise & Warnungen enthalten soll.
Damit ist doch klar, das Doppelt-Initialisierungen damit nicht gemeint sind.

[edit]
Wenn es dokumentiert ist, das der Compiler das so macht, ist das OK.
Wenn Du Dir nicht sicher bist, das der Compiler das so macht, initialisierte selbst.
Ein ich habe es ausprobiert und der Compiler hat es so initialisiert, finde ich nicht ok. (undokumentiertes Verhalten, kann sich ja auch in der nächsten Compiler Version ändern)
Bzw.: Bei Deinem Test einer lokalen Variable i: Integer ist zufällig 0 enthalten. Daraus kannst Du nicht schließen, dass es immer 0 ist.
Lokale Variablen werden NICHT initialisiert, das ist dokumentiert !!!
[/edit]

DeddyH 30. Apr 2012 12:19

AW: Übergebenes nil erkennen?
 
Werden wir jetzt nicht ein wenig zu sehr OT? :roll:

MaBuSE 30. Apr 2012 12:48

AW: Übergebenes nil erkennen?
 
Zitat:

Zitat von DeddyH (Beitrag 1164261)
Werden wir jetzt nicht ein wenig zu sehr OT? :roll:

Nicht direkt,
das Problem des Fragestellers ist ja, dass eine Variable, die nicht initialisiert wurde, nicht mit 0 (nil) initialisiert war.
Wenn er in der Create diese Variablen mit nil initialisiert funktioniert es.
Das hat er ja selbst geschrieben.
Wobei es sich bei seine Variablen um Objektinstanzdaten (Felder) handelt, die eigentlich mit 0 initialisiert werden sollten.
Sie es aber aus welchem Grund auch immer nicht sind. -> selbst initialisieren ist in diesem Fall also durchaus OK :lol:

In der Hilfe steht:
ms-help://embarcadero.rs_xe/rad/Variablen.html
Wenn Sie eine globale Variable nicht explizit initialisieren, wird sie vom Compiler mit 0 initialisiert. Objektinstanzdaten (Felder) werden auch mit 0 initialisiert. Auf der Wiin32-Plattform ist der Inhalt von lokalen Variablen so lange undefiniert, bis ein Wert zugewiesen wird.

mkinzler 30. Apr 2012 12:54

AW: Übergebenes nil erkennen?
 
Das gilt aber nicht für lokale Variablen und Feldern von Klassen (wie in diesem Fall). Hier sollte man immer initialisieren

himitsu 30. Apr 2012 13:07

AW: Übergebenes nil erkennen?
 
Zitat:

Wenn Sie eine globale Variable nicht explizit initialisieren, wird sie vom Compiler mit 0 initialisiert. Objektinstanzdaten (Felder) werden auch mit 0 initialisiert. Auf der Win32-Plattform ist der Inhalt von lokalen Variablen so lange undefiniert, bis ein Wert zugewiesen wird.
Globale und Objekt-Felder
Lokale


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:41 Uhr.
Seite 1 von 2  1 2      

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