![]() |
Delphi-Version: 10.2 Tokyo
Variable ist möglicherweise nicht initialisiert worden
Hallo!
Ich frage mich schon länger, ob die Validierung bzgl. der Warnung "Variable 'foo' ist möglicherweise nicht initialisiert worden" nicht ein überempfindliches Mimöschen ist. Ein Beispiel:
Delphi-Quellcode:
Da fällt mir nun wirklich keine Möglichkeit ein, wie "LEncoding" nicht initialisiert sein könnte. Ist der Compiler nicht intelligent genug, die For-Schleife und das den Schleifenzähler bedingende Case in eine Verbindung zu setzen? Oder kann man das in der Konfiguration beeinflussen? Außer natürlich, die Warnung komplett abzuschalten, was ich keinesfalls möchte.
var
I: Integer; LEncoding: TEncoding; LEncodings: TStringList; begin LEncodings := TStringList.Create; try for I := 1 to 6 do begin case I of 1: LEncoding := TEncoding.ANSI; 2: LEncoding := TEncoding.ASCII; 3: LEncoding := TEncoding.BigEndianUnicode; 4: LEncoding := TEncoding.Unicode; 5: LEncoding := TEncoding.UTF7; 6: LEncoding := TEncoding.UTF8; end; LEncodings.AddObject(LEncoding.EncodingName, LEncoding); // <-- Warnung bzgl. "LEncoding" end; TOpenTextFileDialog(Sender).Encodings.Assign(LEncodings); finally FreeAndNil(LEncodings); end; end; Grüße Cody |
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
Würden für die Grenzen der For-Schleife Variablen verwendet, wäre es sogar noch komplizierter. Dann müsste man die Belegung der Variablen analysieren. Es sollte aber gehen, wenn du in das case einen else-Zweig mit einer Exception einbaust.
Delphi-Quellcode:
case I of
1: LEncoding := TEncoding.ANSI; 2: LEncoding := TEncoding.ASCII; 3: LEncoding := TEncoding.BigEndianUnicode; 4: LEncoding := TEncoding.Unicode; 5: LEncoding := TEncoding.UTF7; 6: LEncoding := TEncoding.UTF8; else raise EProgrammerNotFound.Create('WTF?'); end; |
AW: Variable ist möglicherweise nicht initialisiert worden
Naja das ist halt ein sehr sehr spezieller Fall, den man in der Realität selten hat.
Bei Schleifen gibt es oft keine Garantie, dass diese durchlaufen werden, weil die Liste oder das Array was man durchläuft leer sein kann. Und ein case muss zusätzlich nicht alle Fälle abdecken. Von daher ist eine Variable die nur innerhalb eines case in einer Schleife initialisiert wird und vorher/nachher nicht mehr allgemein eine mögliche Fehlerquelle. Der Compiler ist in deinem speziellen Fall nicht so schlau, genau zu erkennen, dass du eine statische Schleife hast mit einem case, dass alle möglichen Fälle abdeckt. Bzw. er ist wahrscheinlich mit Absicht nicht so schlau, weil solche Fälle in "freier Wildbahn" so selten vorkommen, dass es einfacher ist nur grob drüber zu gucken, als jedes Konstrukt bis ins tiefste zu analysieren für die 0,1% der Fälle wo kein Problem auftreten kann. |
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
|
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
|
AW: Variable ist möglicherweise nicht initialisiert worden
Das Else ist nicht überflüssig, denn es ist ein Schutz, falls mal jemand auf die dusselige Idee kommt und einen Case entfernt. Ohne Else bekommst du eine Warnung und mit Else gibt es eine Exception wenn nicht alle Fälle behandelt wurden.
Das ist ein Feature. |
AW: Variable ist möglicherweise nicht initialisiert worden
Da war der schokohase schneller. Das else sollte immer dabei sein. Genauso wie ich immer eine Basisinitialisierung vornehme:
Delphi-Quellcode:
Ist eigentlich überflüssig, aber sicher.
begin
max:=cMax; if a>20 then max:=50 else max:=100; ........ Gruß K-H |
AW: Variable ist möglicherweise nicht initialisiert worden
Und das nachdem man jahr(zehnt)elang geübt hat, möglichst schlanken und übersichtlichen Code zu schreiben ^^
|
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
Wegen der Übersichtlichkeit (und im Hinblick auf Geschwindigkeit) würde ich das ganze sogar noch ganz anders angehen.
Delphi-Quellcode:
var
LEncodings: TStringList; lEncoding: TEncoding; begin LEncodings := TStringList.Create; try for lEncoding in TArray<TEncoding>.Create(TEncoding.ANSI, TEncoding.ASCII, TEncoding.BigEndianUnicode, TEncoding.Unicode, TEncoding.UTF7, TEncoding.UTF8) do LEncodings.AddObject(lEncoding.EncodingName, lEncoding); TOpenTextFileDialog(Sender).Encodings.Assign(LEncodings); finally LEncodings.Free(); end; end; |
AW: Variable ist möglicherweise nicht initialisiert worden
Nichts für ungut, das erinnert mich an diesen Einzeilercode, den es vor 30 Jahren in jeder Computerfachzeitschrift gab. Die erste Version scheint mir wesentlich übersichtlicher.
Gruß K-H |
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
|
AW: Variable ist möglicherweise nicht initialisiert worden
Ist das Zebra nun schwarz mit weißen Streifen oder weiß mit schwarzen Streifen? ^^
Der Code im Erstpost war ein Beispiel, an dem ich mein Anliegen leicht demonstrieren konnte. Im "richtigen Leben" sind die Dinge ungleich komplexer. |
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
|
AW: Variable ist möglicherweise nicht initialisiert worden
Zitat:
BTT: Schreibt man den "Einzeiler" von Schokohase etwas anders ist er dennoch übersichtlich:
Delphi-Quellcode:
Es ist oft nur eine Sache des Schreibstils, der die Übersichtlichkeit ändert.
var
LEncodings: TStringList; lEncoding: TEncoding; begin LEncodings := TStringList.Create; try for lEncoding in TArray<TEncoding>.Create(TEncoding.ANSI, TEncoding.ASCII, TEncoding.BigEndianUnicode, TEncoding.Unicode, TEncoding.UTF7, TEncoding.UTF8) do LEncodings.AddObject(lEncoding.EncodingName, lEncoding); TOpenTextFileDialog(Sender).Encodings.Assign(LEncodings); finally LEncodings.Free(); end; end; |
AW: Variable ist möglicherweise nicht initialisiert worden
Der Vorteil bei der Schreibweise mit dem generischen Array ist, daß Elemente nur an einer Stelle hinzugefügt bzw. entfernt werden müssen. Auch das Ändern der Reihenfolge ist einfacher. Bei der For-Schleife mit case-Anweisung sind immer zwei Dinge zu beachten. Fügt man nur ein neues case-Label ein und vergisst, die For-Schleife anzupassen, wundert man sich, warum das neue Encoding nicht angezeigt wird. Löscht man eines der case-Label ohne die For-Schleife anzupassen, ergibt die besagte Warnung plötzlich durchaus einen Sinn.
|
AW: Variable ist möglicherweise nicht initialisiert worden
Am gezeigten Beispiel habt ihr natürlich recht. Das generische Array kann man glaub ich auch noch per
Delphi-Quellcode:
abkürzen. Das for-in-[...]-Konstrukt benutze ich inzwischen sogar sehr gerne (schreibe sogar eigene Enumeratoren). Das einzige das mir da fehlt, ist eine Entsprechung zum alten for-a=b-downto-c-Konstrukt.
[TEncoding.ANSI, TEncoding.ASCII {...}]
|
AW: Variable ist möglicherweise nicht initialisiert worden
Dazu möchte ich das DocWiki zitieren:
Zitat:
Delphi-Quellcode:
zu verwenden und den Default-Wert erst nach dem durchlaufen zu setzen.
Exit
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 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