This compiles and never runs the loop:
var i: integer;
n: cardinal;
begin
n := MaxInt + 2;
writeln(n);
for i := 0 to n - 1 do begin
writeln(i);
end;
end.
This compiles and runs the loop many many times:
var i: cardinal;
n: cardinal;
begin
n := 0;
writeln(n);
for i := 0 to n - 1 do begin
writeln(i);
end;
end.
While one could argue that the compiler should warn in the first case due to the different types the second case definitely needs constant propagation. You can enable that using
-Ooconstprop though the calls to
Writeln() seem to mess that up (can probably be considered a bug). If you replace those calls with another one then you'll notice the following errors:
For your first example at the line of the for-loop:
Warning: range check error while evaluating constants (2147483649 must be between -2147483648 and 2147483647)
For your second example also at the line of the for-loop (though strangely this error disappears if range checks are enabled with -CR

):
Warning: range check error while evaluating constants (-1 must be between 0 and 4294967295)
Note: tested with trunk.
And this prints 10000. Apparently all smaller types are converted to sizeint/sizeuint when used
var b: byte;
begin
b := 100;
writeln(b * b);
end.
This one is in fact
documented (the remark before the
Boolean types section).