2
votes

Please help me regression test, and determine in Which Delphi versions the code below fails.

Edit: I know there is a compiler hint for it; it was in fact found in a project I inherited that somehow had the compiler hints turned off (something I see a lot of people do, as they think compiler hints are always harmless, this case shows it is not).
Still I want to know in which Delphi versions this compiler anomaly is present for documentation purposes.

[DCC Hint] QC90921_SO4717399TestCase.pas(47): H2135 FOR or WHILE loop executes zero times - deleted

In Delphi XE, 2009, 2007, and 5, it fails with the output below.
I didn't have time yet to investigate other Delphi versions.
Please help me with that, and answer with which other Delphi versions it fails as well.

Low/High const fail: 0
Low/High hex literal fail: 0
Low/High decimal literal fail: 0

This is the code that is also part of QC 90921:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  CardinalIndex: Cardinal;
  CardinalFirst: Cardinal;
  CardinalLast: Cardinal;
  Count: Int64;
  Target: Int64;
begin
  try
    Target := High(Cardinal);
    Inc(Target);

    Count := 0;
    for CardinalIndex := Low(CardinalIndex) to High(CardinalIndex) do
      Inc(Count);
    if Target <> Count then
      Writeln('Low/High const fail: ', Count);

    Count := 0;
    for CardinalIndex := 0 to $FFFFFFFF do
      Inc(Count);
    if Target <> Count then
      Writeln('Low/High hex literal fail: ', Count);

    Count := 0;
    for CardinalIndex := 0 to 4294967295 do
      Inc(Count);
    if Target <> Count then
      Writeln('Low/High decimal literal fail: ', Count);

    Count := 0;
    CardinalFirst := Low(Cardinal);
    CardinalLast := High(Cardinal);
    for CardinalIndex := CardinalFirst to CardinalLast do
      Inc(Count);
    if Target <> Count then
      Writeln('Low/High variable fail: ', Count);

    Count := 0;
    CardinalFirst := 0;
    CardinalLast := $FFFFFFFF;
    for CardinalIndex := CardinalFirst to CardinalLast do
      Inc(Count);
    if Target <> Count then
      Writeln('hex literal Variable fail: ', Count);

    Count := 0;
    CardinalFirst := 0;
    CardinalLast := 4294967295;
    for CardinalIndex := CardinalFirst to CardinalLast do
      Inc(Count);
    if Target <> Count then
      Writeln('decimal literal Variable fail: ', Count);

    Write('Press <Enter>');
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Edit: summary of the answers; it fails in these Delphi versions:

  • 5
  • 6
  • 7
  • 2006
  • 2007
  • 2009
  • 2010
  • XE

--jeroen

4
FWIW it is documented, see the bottom of: docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/…Sertac Akyuz
Your problem is that your for loops terminate instantly instead of running for 2^32 iterations? But only if the start/end values are compiletime constants, but not if they are variables.CodesInChaos
@Sertac - you should post this link as the/an answer.Deltics
@Deltics - It's a bit of a speculation since I haven't done any tests, but answered anyway.Sertac Akyuz
Same output with Delphi 7, first two loops are deleted (FOR or WHILE loop executes zero times - deleted). See Sertac Akyuz's answer.The_Fox

4 Answers

4
votes

I guess, since this is a documented defect, all versions where High(Cardinal) > High(Longint) (Delphi 4 and up) would exhibit the behavior.

From "H2135: FOR or WHILE loop executes zero times - deleted (Delphi)":

You may see this warning if a FOR loop increments its control variable from a value within the range of Longint to a value outside the range of Longint. For example:
var I: Cardinal;
begin
  For I := 0 to $FFFFFFFF do
...
This results from a limitation in the compiler which you can work around by replacing the FOR loop with a WHILE loop.
1
votes

I'm not sure this is a real SO question that Jeff would approve of, but here is the output from D2010:

Low/High const fail: 0
Low/High literal fail: 0
Press <Enter>

Delphi 6 produces the same output.

1
votes

Delphi 2006:

[Pascal Hint] Project1.dpr(20): H2135 FOR or WHILE loop executes zero times - deleted
[Pascal Hint] Project1.dpr(26): H2135 FOR or WHILE loop executes zero times - deleted
[Pascal Hint] Project1.dpr(32): H2135 FOR or WHILE loop executes zero times - deleted

Output:

Low/High const fail: 0
Low/High hex literal fail: 0
Low/High decimal literal fail: 0
1
votes

Same output with Delphi 7, first two loops are deleted (FOR or WHILE loop executes zero times - deleted). See Sertac Akyuz's answer.

Edit:

Same with Turbo Delphi 2006, first three loops are deleted with the same hint.