Ich bin neu in Delphi und habe einige Tests durchgeführt, um festzustellen, auf welche Objektvariablen und Stapelvariablen standardmäßig initialisiert wird:
TInstanceVariables = class
fBoolean: boolean; // always starts off as false
fInteger: integer; // always starts off as zero
fObject: TObject; // always starts off as nil
end;
Dies ist das Verhalten, das ich von anderen Sprachen gewohnt bin, aber ich frage mich, ob es sicher ist, sich in Delphi darauf zu verlassen? Ich frage mich beispielsweise, ob dies möglicherweise von einer Compilereinstellung abhängt oder auf verschiedenen Computern unterschiedlich funktioniert. Ist es normal, sich auf initialisierte Standardwerte für Objekte zu verlassen, oder legen Sie explizit alle Instanzvariablen im Konstruktor fest?
Was Stapelvariablen (Prozedurebene) betrifft, zeigen meine Tests, dass unitialisierte Boolesche Werte wahr sind, unitialisierte Ganzzahlen 2129993264 sind und nicht initialisierte Objekte nur ungültige Zeiger sind (dh nicht Null). Ich vermute, die Norm ist, immer Variablen auf Prozedurebene festzulegen, bevor auf sie zugegriffen wird.
Antworten:
Ja, dies ist das dokumentierte Verhalten:
Objektfelder werden immer mit 0, 0.0, '', False, nil oder was auch immer initialisiert initialisiert.
Globale Variablen werden immer auch auf 0 usw. initialisiert.
Lokale referenzgezählte * Variablen werden immer mit nil oder '' initialisiert.
Lokale nicht referenzgezählte * Variablen sind nicht initialisiert, daher müssen Sie einen Wert zuweisen, bevor Sie sie verwenden können.
Ich erinnere mich, dass Barry Kelly irgendwo eine Definition für "referenzgezählt" geschrieben hat, diese aber nicht mehr finden kann. Das sollte in der Zwischenzeit so sein:
Anmerkungen:
record
selbst reicht nicht aus, um als Referenz gezählt zu werdenquelle
TObject.Create
einer ungültigen Methode, sondernclass function TObject.InitInstance(Instance: Pointer): TObject;
wird IMMER vor jedem Konstruktoraufruf aufgerufen, selbst bei älteren Delphi-Versionen. Ihr Kommentar ist meiner Meinung nach falsch und verwirrend.Globale Variablen ohne expliziten Initialisierer werden im BSS-Abschnitt in der ausführbaren Datei zugewiesen. Sie nehmen in der EXE eigentlich keinen Platz ein. Der BSS-Abschnitt ist ein spezieller Abschnitt, den das Betriebssystem zuweist und auf Null löscht. Auf anderen Betriebssystemen gibt es ähnliche Mechanismen.
Sie können sich darauf verlassen, dass globale Variablen auf Null initialisiert werden.
quelle
Klassenfelder sind standardmäßig Null. Dies ist dokumentiert, damit Sie sich darauf verlassen können. Lokale Stapelvariablen sind undefiniert, es sei denn, Zeichenfolge oder Schnittstelle werden auf Null gesetzt.
quelle
Nur als Randnotiz (da Sie Delphi noch nicht kennen): Globale Variablen können direkt beim Deklarieren initialisiert werden:
quelle
Hier ist ein Zitat von Ray Lischners Delphi in Kürze, Kapitel 2
Es ist wahr, dass Variablen im lokalen Bereich initialisiert werden müssen ... Ich würde den obigen Kommentar, dass "Globale Variablen initialisiert werden", als zweifelhaft behandeln, bis sie mit einer Referenz versehen werden - das glaube ich nicht.
edit ... Barry Kelly sagt, dass Sie sich darauf verlassen können, dass sie auf Null initialisiert sind, und da er im Delphi-Compiler-Team ist, glaube ich, dass das so ist :) Danke Barry.
quelle
Globale Variablen und Objektinstanzdaten (Felder) werden immer auf Null initialisiert. Lokale Variablen in Prozeduren und Methoden werden in Win32 Delphi nicht initialisiert. Ihr Inhalt ist undefiniert, bis Sie ihnen einen Wert im Code zuweisen.
quelle
Selbst wenn eine Sprache Standardinitialisierungen bietet, sollten Sie sich meiner Meinung nach nicht darauf verlassen. Das Initialisieren auf einen Wert macht es anderen Entwicklern viel klarer, die möglicherweise nichts über Standardinitialisierungen in der Sprache wissen, und verhindert Probleme zwischen Compilern.
quelle
Aus der Delphi 2007-Hilfedatei:
ms-help: //borland.bds5/devcommon/variables_xml.html
quelle
Ich habe einen kleinen Kritikpunkt mit den gegebenen Antworten. Delphi setzt den Speicherplatz der Globals und der neu erstellten Objekte auf Null. Während dies NORMAL bedeutet, dass sie initialisiert werden, gibt es einen Fall, in dem dies nicht der Fall ist: Aufzählungstypen mit bestimmten Werten. Was ist, wenn Null kein legaler Wert ist?
quelle
TOneTwoThree = (One=1, Two=2, Three=3);
Neu eingeführte (seit Delphi 10.3) Inline-Variablen erleichtern die Steuerung von Anfangswerten.
quelle