Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Compiler warnt nicht vor nicht initialisierter Variable (https://www.delphipraxis.net/185290-compiler-warnt-nicht-vor-nicht-initialisierter-variable.html)

Der schöne Günther 28. Mai 2015 12:33

Compiler warnt nicht vor nicht initialisierter Variable
 
XE7. Windows, 32 und 64 Bit, Debug und Release.

Folgendes Beispiel:
Delphi-Quellcode:
program Project27;

{$APPTYPE CONSOLE}

{$R *.res}

procedure forProc();
var
   myArray:   TArray<Single>;
   arrayIndex:   Integer;
begin
   for arrayIndex := Low(myArray) to High(myArray) do
      if (arrayIndex = 42) then Break;

   WriteLn(arrayIndex);
   readln;
end;

begin
   forProc();
end.
Die Variable
Delphi-Quellcode:
arrayIndex
kann klar undefiniert sein. Zur Laufzeit ist sie es tatsächlich auch, denn das Array ist leer. In der Konsole steht dann z.B.
Delphi-Quellcode:
435345345
.

Warum warnt der Compiler davor nicht? Kommentiert man das
Delphi-Quellcode:
if (arrayIndex = 42) then Break;
aus, dann gibt es vernünftigerweise einen
Code:
[dcc32 Warnung] Project27.dpr(12): W1037 FOR-Schleifenvariable 'arrayIndex' kann nach Durchlauf undefiniert sein

himitsu 28. Mai 2015 12:50

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Delphi-Quellcode:
for arrayIndex := Low(myArray) to High(myArray) do
begin
  if (arrayIndex = 42) then
    Break;
end;
WriteLn(arrayIndex); // Die Variable ist außerhalb natürlich undefiniert, da Schleifenvariablen nach der Schleife keinen definierten Zustand besitzen. :roll:
"kann nach Durchlauf undefiniert sein" und "Variable nicht initialisiert" ist ja im Grunde das Selbe Gleiche.

Aber man weiß ja, daß der Compiler manchmal nicht ganz weiß was er macht und dann die falsche Fehlermeldung bringt, wobei sie hier natürlich richtig ist, auch wenn es jeweils ein bissl anders klingt.

Der schöne Günther 28. Mai 2015 13:01

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Ich verstehe nicht- Bekommst du eine Warnung? Ich nicht.

himitsu 28. Mai 2015 13:11

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Hab's nicht getestet (hier im XE oder 7), aber es ist/wäre vollkommen korrekt, wenn bei
Delphi-Quellcode:
WriteLn(arrayIndex);
eine Warnung kommt, daß die Variable dort nicht (mehr) initialisiert ist, denn das ist sie auch nicht.

Hab das "nicht" nicht gelesen.
Hmmm, entweder ein Bug ... kann daheim dann nochmal nachsehn, aber mir ist so, als wenn da immer gewarnt wurde (wobei ich sowas selten mach)

nuclearping 28. Mai 2015 15:49

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Habs mal mit XE2 und XE7 getestet. Gleiches Ergebnis wie Günther schon sagte. Ich erhalte keine Warnung und
Delphi-Quellcode:
WriteLn(arrayIndex)
gibt Müll aus. Wenn ich die
Delphi-Quellcode:
if (arrayIndex ...)
-Prüfung auskommentiere, erhalte ich auch eine W1037-Warnung.

Union 28. Mai 2015 16:30

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Der Compiler kann zur Compilezeit ja nicht wissen dass High(myArray) = -1 ist. Er sieht nur das for-Konstrukt in dem ja theoretisch eine Zuweisung erfolgt.

Sailor 28. Mai 2015 17:36

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Das liegt an der Break-Anweisung. Der Compiler stellt nach dem Break den aktuellen Schleifenindex zur Verfügung. Kommentiere nur das Break aus, dann dürfte eine Warnung kommen.

Der schöne Günther 28. Mai 2015 17:43

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Aber wir wären uns alle einig dass wir Embarcaderos "Reported Bugs" wieder um eins größer machen sollten, oder?

himitsu 28. Mai 2015 18:19

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Jupp, so schnell wie möglich melden.
Jede Stunde früher scheint 'nen Monat eher bereinigt zu sein.

Man könnte noch schauen, was die verschiedenen Compiler dazu sagen (Win64, iOS32, iOS64, OSX, Linux, ...)
und mit oder ohne Generics.

Der schöne Günther 28. Mai 2015 18:31

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Höre ich da Sarkasmus?

Win64 hatte ich eingangs auch geprüft, die anderen Plattformen kann ich nicht. Wäre mal interessant. Wäre jemand so freundlich? :angel2:

Übrigens: Die
Delphi-Quellcode:
for..in
-Schleife ist nicht betroffen.

gammatester 29. Mai 2015 08:51

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Zitat:

Zitat von Sailor (Beitrag 1303424)
Das liegt an der Break-Anweisung. Der Compiler stellt nach dem Break den aktuellen Schleifenindex zur Verfügung. Kommentiere nur das Break aus, dann dürfte eine Warnung kommen.

Das Verlassen der Schleife kann aber nicht der einzige Grund sein, ersetzt man das break durch ein goto
Delphi-Quellcode:
procedure forProc();
label xx;
var
   myArray:  TArray<Single>;
   arrayIndex:  Integer;
begin
   for arrayIndex := Low(myArray) to High(myArray) do
      if (arrayIndex = 42) then goto xx;
xx:
   WriteLn(arrayIndex);
   readln;
end;
dann erhält man 3 (in Worten drei) mal die gleiche Warnung.

himitsu 29. Mai 2015 08:56

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Zitat:

Zitat von Sailor (Beitrag 1303424)
Das liegt an der Break-Anweisung. Der Compiler stellt nach dem Break den aktuellen Schleifenindex zur Verfügung.

Nein, außerhalb der Schleife ist die Schleifenvariable per se immer "ungültig".

Ja, es kann "zufällig" mal sein, daß die Variable danach noch den selben Wert hat, aber wenn hier eine der möglichen Optimierungen zuschlägt, dann war's das damit.
* der Compiler lässt intern die Zählung eventuell rückwärts laufen, wenn er das für optimaler erachtet
* oder er lässt die Variable wärend der Schleife in einem der CPU-Registier und kopiert es danach natürlich nicht in die Variable auf dem Stack, da das sinnlos wäre, weil laut Definition danach die Schleifenvariable nicht mehr verwendet wird.
* ...

Sailor 29. Mai 2015 14:58

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Delphi-Quellcode:
   FUNCTION TestIndex:Boolean;
    LABEL
     Stop;

    VAR
     i: Integer;

    BEGIN
     Result := False;

     FOR i:=0 TO 10          // Schleife 1
      DO ;
     IF i = 8
      THEN ;
// [DCC Warning] Test.pas(12): W1037 FOR-Loop variable 'i' may be undefined after loop

     FOR i:=0 TO 10          // Schleife 2
      DO IF i = 8
          THEN Break;
     IF i = 8
      THEN ;
// Keine Warnung

// Diese Zeilen hinzufügen
// Dann wird es lustig:
     FOR i:=0 TO 10          // Schleife 3
      DO IF i = 8
          THEN GOTO Stop;
  Stop:
     IF i = 8
      THEN ;
[DCC Warning] Test.pas(27): W1037 FOR-Loop variable 'i' may be undefined after loop
[DCC Warning] Test.pas(12): W1037 FOR-Loop variable 'i' may be undefined after loop
[DCC Warning] Test.pas(27): W1037 FOR-Loop variable 'i' may be undefined after loop
[DCC Warning] Test.pas(12): W1037 FOR-Loop variable 'i' may be undefined after loop
    END;
Na ja, vielleicht vom Übergang von früheren Delphiversionen auf Delphi5 an klappte die Technik von Schleife 2 und man konnte sich das Hochzählen einer temporären Variablen parallel zum Schleifenindex sparen. Jedenfalls schien mir das durch die nun fehlende Warnung gerechtfertigt zu sein. Ich habe das dann bis jetzt (D2010) ziemlich intensiv genutzt und bin auch noch nicht hingefallen :)
Aber was da nach dem Hinzufügen von Schleife 3 angezeigt wird, macht einen natürlich nachdenklich.

jbg 29. Mai 2015 15:44

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Zitat:

Zitat von himitsu (Beitrag 1303427)
Man könnte noch schauen, was die verschiedenen Compiler dazu sagen (Win64, iOS32, iOS64, OSX, Linux, ...)
und mit oder ohne Generics.

Was sollen die anderes sagen, die haben alles das gleiche Frontend. Nur das Backend ist je unterschiedlich bzw. LLVM.

himitsu 29. Mai 2015 16:32

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Ich dachte Win/Win32 ist immernoch das Alte und noch nix mit LLVM?

jbg 29. Mai 2015 19:09

AW: Compiler warnt nicht vor nicht initialisierter Variable
 
Zitat:

Zitat von himitsu (Beitrag 1303559)
Ich dachte Win/Win32 ist immernoch das Alte und noch nix mit LLVM?

Habe ich was anderes geschrieben? "bzw." heißt nicht dass alles LLVM ist, sondern nur ein Teil (die Mobile-Compiler und BCB64)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:24 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