2008-09-25 11 views
84

Ich bin neu in Delphi, und ich habe einige Tests wurde ausgeführt, um zu sehen, welche Objektvariablen und Stack-Variablen standardmäßig initialisiert werden:Sind Delphi-Variablen standardmäßig mit einem Wert initialisiert?

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 aus anderen Sprachen gewohnt bin Aber ich frage mich, ob man sich in Delphi darauf verlassen kann. Ich frage mich zum Beispiel, ob es von einer Compiler-Einstellung abhängen könnte oder vielleicht auf verschiedenen Rechnern anders funktioniert. Ist es normal, sich auf voreingestellte initialisierte Werte für Objekte zu verlassen, oder setzen Sie explizit alle Instanzvariablen im Konstruktor? Wie für Stapelvariablen (Prozedurebenen) zeigen meine Tests, dass unitialisierte Boolesche Werte wahr sind, unitäre Ganzzahlen sind 2129993264 und nicht initialisierte Objekte sind nur ungültige Zeiger (d. H. Nicht NULL). Ich schätze, die Norm ist, immer Variablen auf Prozedurenebene zu setzen, bevor Sie darauf zugreifen.

+1

Zwei Anmerkungen: 1. Aufzeichnungen initialisiert werden nicht können globale Variablen direkt ihnen bei der Deklaration initialisiert werden. 2. Referenzzählungsvariablen werden immer initialisiert. !ABER! In einer Funktion, die eine Zeichenfolge zurückgibt, wird "Result" nicht wie erwartet mit einer leeren Zeichenfolge initialisiert. Dies liegt daran, dass 'Ergebnis' keine lokale Variable ist. Also immer: Ergebnis: = ''; – Ampere

+0

siehe auch: [Welche Variablen werden in Delphi initialisiert?] (Http://stackoverflow.com/questions/861045/which-variables-are-initialized-when-in-delphi) – Ampere

Antwort

89

Ja, das ist das dokumentierte Verhalten:

  • Objektfelder auf 0 immer initialisiert, 0.0, '', Falsch, null oder was auch immer zutrifft.

  • Globale Variablen werden immer auf 0 usw. initialisiert;

  • Lokale Referenz-gezählte * Variablen werden immer auf Null oder '' initialisiert;

  • Lokale Variablen ohne Referenzzählung * 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 „Referenzzählung“ geschrieben, aber kann es nicht mehr finden, so dass diese in der Zwischenzeit tun soll:

Referenz gezählt ==, die referenzgezählt selbst oder direkt oder indirekt enthalten Felder (für Datensätze) oder Elemente ( arrays), die mit Referenzzählung sind wie: string, variant, interface oder dynamisches Array oder statisches Array haltende ng solcher Arten.

Hinweise:

  • record selbst ist nicht genug Referenz gezählt werden
  • Ich habe nicht versucht mit Generika noch
+2

Wie Giacomo in den Kommentaren darauf hingewiesen hat, wird dies alles in den Delphi-Hilfedateien unter ms-help: //borland.bds4/bds4ref/html/Variables.htm erklärt. In Delphi 2009 habe ich die gleichen Informationen gefunden, indem ich die Hilfe nach "Variablen" durchsucht habe (lustigerweise habe ich viele Suchen versucht, aber ich habe nicht daran gedacht, das zu versuchen). –

+8

Lokale Variablen werden initialisiert ($ 0), wenn sie verwalteten Typs wie Strings, Interfaces, dynamische Arrays oder Varianten sind –

+2

Wenn dies die 'Antwort' ist, sollte jemand hinzufügen, welche Sets und enums zur Vollständigkeit initialisiert werden. –

17

Klassenfelder sind standardmäßig Null. Dies ist dokumentiert, damit Sie sich darauf verlassen können. Lokale Stapelvariable sind nicht definiert, es sei denn, es handelt sich um einen String oder eine Schnittstelle, diese werden auf Null gesetzt.

+0

Danke. "Zero" verwirrte mich ein wenig - bedeutet das, dass Strings "" sind und Interfaces keine sind? –

+4

Ja, genau das. nil = 0 (auf der Assembler-Ebene) und '' = nil (Delphi-Konvention). – gabr

+0

Prost - das macht Sinn, danke! –

4

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.

2

Auch wenn eine Sprache Standardinitialisierungen anbietet, glaube ich nicht, dass Sie sich darauf verlassen sollten.Durch das Initialisieren auf einen Wert wird es anderen Entwicklern, die die Standardinitialisierungen in der Sprache möglicherweise nicht kennen, viel klarer und verhindert Probleme in Compilern.

+3

Natürlich können Sie. Und du solltest. Alles in 0/'/ false/nil in jedem Konstruktor zu initialisieren ist einfach unnötig. Das Initialisieren von globalen Variablen ist andererseits nicht so dumm - ich kann mich für einmal nicht erinnern, ob sie initialisiert sind oder nicht (weil ich sie nicht viel benutze). – gabr

+1

Wenn Delphi Sie eine Variable an dem gleichen Punkt initialisieren lassen, wie Sie es deklarieren (z. B. var fObject: TObject = nil) würde ich geneigt sein zuzustimmen, dass die Initialisierung auf einen Wert wahrscheinlich eine gute Idee ist. Aber mir scheint es ein wenig zu viel im Konstruktor für jedes Objektfeld zu tun. –

8

Hier ist ein Zitat von Ray Lischners Delphi in a Nutshell Chapter 2

„Wenn Delphi zunächst ein Objekt erstellt, alle Felder beginnen leer, das heißt, sind Zeiger auf Null initialisiert, Strings und dynamische Arrays leer sind, haben Zahlen den Wert Null, Boolean Felder sind falsch, und Varianten sind nicht zugewiesen eingestellt. (Siehe NewInstance und InitInstance in Kapitel 5 für weitere Einzelheiten.)“

Es stimmt, dass local-in-scope Variablen müssen initialisiert werden ... Ich würde den obigen Kommentar behandeln: "Globale Variablen sind initia "so zweifelhaft, bis mit einer Referenz versehen - das glaube ich nicht.

bearbeiten ... Barry Kelly sagt, Sie können sich darauf verlassen, dass sie Null-Initialisierung, und da er auf dem Delphi-Compiler-Team ist glaube ich, dass steht :) Danke Barry.

+0

In Delphi 2006 Hilfe finden Sie es hier: ms-help: //borland.bds4/bds4ref/html/Variables.htm "Wenn Sie eine globale Variable nicht explizit initialisieren, initialisiert der Compiler es auf 0. Objektinstanz Daten (Felder) werden ebenfalls auf 0 initialisiert. " –

4

Von Delphi 2007-Hilfedatei:

ms-help: //borland.bds5/devcommon/variables_xml.html

„Wenn Sie nicht explizit eine globale Variable initialisieren, der Compiler initialisiert es auf 0. "

3

Ich habe ein wenig meckern mit den Antworten gegeben. Delphi löscht den Speicherplatz der Globals und der neu erstellten Objekte aus. Während diese NORMAL bedeutet, dass sie initialisiert werden, gibt es einen Fall, in dem sie nicht sind: Aufzählungstypen mit bestimmten Werten. Was ist, wenn Null kein zulässiger Wert ist?

+1

Null ist immer ein zulässiger Wert, es ist der erste Wert der Aufzählung. Sie können es mit Ord (MyFirstEnumValue) sehen. –

+0

Es würde den ersten Wert im Aufzählungstyp zurückgeben. – skamradt

+5

Null ist nicht immer ein zulässiger Wert, wenn Sie der Aufzählung explizit Werte zuweisen. In diesem Fall ist es immer noch auf 0 initialisiert und Sie haben einen ungültigen Wert. Aber Enums sind nur syntaktischer Zucker, der über normale Integer-Typen gemalt wird, so dass dies nichts wirklich bricht. Stellen Sie sicher, dass Ihr Code damit umgehen kann. –

24

Globale Variablen, die keinen expliziten Initialisierer haben, werden im BSS-Abschnitt in der ausführbaren Datei zugeordnet. Sie nehmen in der EXE keinen Platz ein; Der BSS-Abschnitt ist ein spezieller Abschnitt, den das Betriebssystem zuordnet und auf Null setzt. Auf anderen Betriebssystemen gibt es ähnliche Mechanismen.

Sie können sich darauf verlassen, dass globale Variablen nicht initialisiert werden.

15

nur als Randnotiz (wie Sie zu Delphi neu):

var myGlobal:integer=99;