loop variable

Top  Previous  Next

What is translated > Statements > for loop's > loop variable

A direct translation of a Delphi loop variable can produce a subtle error when the loop reaches the highest or lowest value representable by that variable type.

 

Consider the following Delphi function:

 

function ToHigh: Boolean;

var

  B: Byte;

  I: Integer;

begin

  I := 0;

 

  for B := Low(Byte) to High(Byte) do

    I := Integer(B);

 

  Result := I = Integer(High(Byte));  // 255

end;

 

A straightforward C# translation would retain the original Byte type:

 

private bool ToHigh()

{

    byte B = 0;  // Incorrect loop-variable type

    int I = 0;

 

    for (B = byte.MinValue; B <= byte.MaxValue; B++)

    {

        I = B;

    }

 

    return I == byte.MaxValue;

}

 

This loop cannot terminate normally. After the iteration with B == 255, the expression B++ is executed. A byte cannot represent the value 256.

 

In an unchecked context, the value wraps around to 0, and the condition B <= byte.MaxValue remains true. The result is an infinite loop. In a checked context, the increment can instead cause an OverflowException.

 

To preserve the Delphi behavior, Delphi2C# changes the loop variable to a wider integral type:

 

private bool ToHigh()

{

    int B = 0;  // Corrected loop-variable type

    int I = 0;

    int stop = 0;

 

    for (stop = byte.MaxValue, B = byte.MinValue;

         B <= stop;

         B++)

    {

        I = B;

    }

 

    return I == byte.MaxValue;

}

 

During the intended iterations, B still has exactly the values of the original Delphi Byte variable. After the final iteration, however, the widened variable can become 256. The loop condition then evaluates to false and the loop terminates correctly.

 

The same problem can occur in a downto loop. If a variable of the original type is decremented after reaching its lowest representable value, it may wrap around or cause an overflow exception. Delphi2C# therefore applies the corresponding type-widening check to both to and downto loops.

 

This check is independent of the stop-variable option:

 



This page belongs to the Delphi2C# Documentation

Delphi2C# home  Content