Initialisierungswerte von Variablen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Initialisierungswerte von Variablen

Beitrag von Euklid »

Ich denke mir, dass defensive Programmierung nicht schadet. Daher vergebe ich allen Variablen in einem Initialisierungs-Abschnitt einen Wert.
Ich vermute aber, dass der Compiler genau bei den Variablen KEINEN Startwert zuweise, bei denen er "Variable doesn't seem to be initialised" (oder so) meckert.

Viele Grüße, Euklid

hendy
Beiträge: 80
Registriert: Sa 11. Apr 2009, 17:01
OS, Lazarus, FPC: Windoof (L 0.9.26 FPC 2.2.2)
CPU-Target: 32Bit

Re: Initialisierungswerte von Variablen

Beitrag von hendy »

So weit ich weiß werden integerwerte nicht initialisiert, es ist nur drinn, was an der Speicherstelle steht.
Ein Kumpel hatte ein Programm, das 2 Zahlen addiert und war dann verzweifelt, warum immer 2351 zuviel rauskommt.
Tja, er hatte keine Initialisierung :D
Dankt monta !!

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Initialisierungswerte von Variablen

Beitrag von theo »

af0815 hat geschrieben:Das Verhalten des FPCs beim initialisieren ist in der Dokumentation erklärt, Kapitel 4.4
Ich glaube das ist ungenau dokumentiert. Natürlich kann eine explizite Initialisierung nicht schaden, aber bei Globalen Var. und Klassenfeldern ist es afaik nicht nötig. Bei Delphi ist es so und der FPC gibt auch keine Warnungen aus für diese Fälle.

Wenn diese Annahme nicht stimmen würde wäre FPC
A: Inkompatibel mit Delphi (Mir ist noch nie ein solches Problem beim portieren von Delphi Klassen aufgefallen)
B: Buggy im Bereich Warnungen.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Initialisierungswerte von Variablen

Beitrag von RSE »

af0815 hat geschrieben:Das Verhalten des FPCs beim initialisieren ist in der Dokumentation erklärt, Kapitel 4.4
Auszug:

Code: Alles auswählen

By default, variables in pascal are not initialized after their declaration. Any assumption that they contain 0 or any other default value is erroneous: They can contain rubbish.
Das schließt eben nicht aus, dass Variablen, wenn sie an bestimmten Stellen stehen (z.B. als Klassenvariablen, globale Variablen etc.), doch initialisiert werden. Sie werden nur nicht immer und überall initialisiert. Die Frage ist, welches sind diese bestimmten Stellen? Wo kann man sich drauf verlassen, dass sie initialisiert werden?
Euklid hat geschrieben:Ich denke mir, dass defensive Programmierung nicht schadet. Daher vergebe ich allen Variablen in einem Initialisierungs-Abschnitt einen Wert.
Damit ist man auf der sicheren Seite, hat aber bestimmt an vielen Stellen jede Menge unnötigen Code, der das Programm nur unübersichtlicher und langsamer macht (wobei die Unübersichtlichkeit heutzutage wohl gewichtiger ist).
hendy hat geschrieben:So weit ich weiß werden integerwerte nicht initialisiert, es ist nur drinn, was an der Speicherstelle steht.
Das hat sicherlich weniger mit dem Typ der Variable (Integer oder String) als vielmehr damit zu tun, wo sie deklariert wurde (lokal, in einer Klasse oder global).
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Initialisierungswerte von Variablen

Beitrag von mse »

Immer mit nil initialisiert werden die referenzgezählten ansisistring, widestring, dynamische Arrays und Interface, FPC liefert hier manchmal die falsche Warnung über nicht initialisierte Variable.
Alle Klassenfelder und globale Variablen werden mit null Bytes vorbelegt (-> false, 0, 0.0, nil...).
Nicht initialisiert werden nicht referenzgezählte lokale Variablen.

Edit:
Ebenfalls mit null initialisiert werden mit setlength() angelegte neue dynamische array items. Die Delphi Dokumentation schreibt zwar, dass lediglich arrays mit dynamischen Feldern initialisiert werden, weder Delphi 7 noch FPC machen diese Unterscheidung. Neuere Delphi Versionen kenne ich nicht. Weiss da jemand etwas genaueres?

Martin
Zuletzt geändert von mse am Sa 17. Okt 2009, 13:15, insgesamt 2-mal geändert.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Initialisierungswerte von Variablen

Beitrag von RSE »

Das klingt doch mal nach einer definitiven Aussage, die sich auch mit allen Beobachtungen deckt!
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

Re: Initialisierungswerte von Variablen

Beitrag von knight »

RSE hat geschrieben:Daher wäre es eben sinnvoll diese Regeln mal im FPC Reference Guide mit aufzunehmen. Aber das muss einer der Dev´s mal machen.
Dann solltest du dich an Michael van Canneyt wenden.

knight

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Initialisierungswerte von Variablen

Beitrag von theo »

RSE hat geschrieben:Das klingt doch mal nach einer definitiven Aussage,
Was? Das ist dir jetzt schon definitiv genug?
Ich möchte noch Stempel und Unterschrift mit Ort und Datum von mindestens fünf Compiler Entwicklern.

;-)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6877
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Initialisierungswerte von Variablen

Beitrag von af0815 »

Für mich es eigentlich definitiv - Im Reference Guide steht drinnen, was initialisiert wird und bei allen anderen muß ich davon ausgehen, das es nicht initialisiert ist. Unabhängig davon was 'irgendwer' festgestellt hat.

Klar kann ich ja auch behaupten, bei Rot kann man über die Starsse gehen und es hat mir gestern nicht geschadet. Würdet ihr dann auch sofort bei Rot dann losrennen (Zumindest die Gene könntet ihr dann aufgrund der nartürlichen Ausese nicht mehr weitergeben :-) SCNR ).
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

khh
Beiträge: 489
Registriert: Sa 5. Apr 2008, 09:37
OS, Lazarus, FPC: Win Vista,Win 7 (L 0.9.29 FPC 2.4.1)
CPU-Target: 32Bit /64 Bit
Wohnort: Nähe Freiburg i.Br.

Re: Initialisierungswerte von Variablen

Beitrag von khh »

sauberer ist es allemal beim Programmstart die Variablen selbst zu initialisieren.
damit erledigen sich alle entsprechenden Diskusionen ;-)


Gruss KHH

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Initialisierungswerte von Variablen

Beitrag von RSE »

af0815 hat geschrieben:Klar kann ich ja auch behaupten, bei Rot kann man über die Starsse gehen und es hat mir gestern nicht geschadet. Würdet ihr dann auch sofort bei Rot dann losrennen (Zumindest die Gene könntet ihr dann aufgrund der nartürlichen Ausese nicht mehr weitergeben :-) SCNR ).
Programmierer gehen auch blind davon aus, dass sich der Prozessor nicht verrechnet, dass die Festplatte nichts vergisst, dass das Betriebssystem korrekt arbeitet und ebenso, dass der Compiler das tut, was seine Entwickler über ihn behaupten. Letzteres wurde hier festgestellt und nun werde ich es anwenden.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

martin_frb
Beiträge: 588
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Initialisierungswerte von Variablen

Beitrag von martin_frb »

mse hat geschrieben:Immer mit nil initialisiert werden die referenzgezählten ansisistring, widestring, dynamische Arrays und Interface, FPC liefert hier manchmal die falsche Warnung über nicht initialisierte Variable.
Alle Klassenfelder und globale Variablen werden mit null Bytes vorbelegt (-> false, 0, 0.0, nil...).
Nicht initialisiert werden nicht referenzgezählte lokale Variablen.
In der tat werden aktuell alle Referenz gezählten variable mit nil initialisiert. Das ist nötig, weil sonst bei der ersten Zuweisung an diese Variable versucht würde den alten Wert freizugeben.
IMHO ist das aber kein dokumentiertes verhalten, das heißt es kann sich in Zukunft ändern.

IIRC gab es mal eine Diskussion
function x(): String; begin end; // keine Zuweisung an Result
und irgendwo anders
a := x();

IIRc in fpc, wir a := nil, in Delphi bleibt a unverändert, oder irgendsowas. Es ist halt nicht definiert was passieren soll.

In Objekten (genau Instanzen einer Klassen Definition "a= class ... end" nicht "a = object .. end") werden tatsächlich alle variablen auf 0/nil gesetzt.
Keine Ahnung ob das dokumentiert ist, aber in einer Diskussion auf der FPC Mail liste wurde folgendes gesagt:
Klass Members werden mit 0/nil initialisiert. Dies ist zb nötig wenn im Konstruktor eine Exception auftritt. In einem solchem Fall wird automatisch der Destruktor aufgerufen. Daher müssen alle Felder mit 0/nil initialisiert sein. So weiß der Destructor das zb eine Objekt in der Variable FChildObject nicht existiert. Sonst würde FChildObject.Free zu einem Crash fuehren, da es ja auf eine zufällige Memory location zeigt.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Initialisierungswerte von Variablen

Beitrag von mse »

martin_frb hat geschrieben:In der tat werden aktuell alle Referenz gezählten variable mit nil initialisiert. Das ist nötig, weil sonst bei der ersten Zuweisung an diese Variable versucht würde den alten Wert freizugeben.
IMHO ist das aber kein dokumentiertes verhalten, das heißt es kann sich in Zukunft ändern.
Dies ist nicht wahrscheinlich, da dann die erste Zuweisung und das Aufräumen am Procedureende nicht mehr funktionieren würde. Aus Prinzip und um um die Compilerwarnung zu vermeiden, mache ich jeweils trotzdem zu Procedurebeginn die nil-Zuweisung. Schön wäre es, wenn der Compiler diese "überflüssigen" Befehle entfernen würde.
IIRC gab es mal eine Diskussion
function x(): String; begin end; // keine Zuweisung an Result
und irgendwo anders
a := x();

IIRc in fpc, wir a := nil, in Delphi bleibt a unverändert, oder irgendsowas. Es ist halt nicht definiert was passieren soll.
Delphi behandelt die return Variable wie einen zusätzlichen var Parameter, die Initialisierung geschieht also irgendwo in den aufrufenden Proceduren. IIRC sind diese Dinge in der Delphi Dokumentation festgehalten.

Antworten