On 27/01/18 16:28, Jonas Maebe wrote:

Jonas Maebe wrote:
C Western wrote:
The following innocuous looking code generates a range check error:

{$R+}
function Count: qword;
begin
   Result := 0;
end;
var
   i: Integer;
begin
   for i := 0 to Count-1 do
     WriteLn(i);
end.

I can (more or less) see why
I changed the type used to evaluate for-loop bounds in ISO Pascal mode
because of https://bugs.freepascal.org/view.php?id=24318 . Maybe the
same should be done for other non-TP/Delphi modes too.

Actually, it won't help because "qword - 1" will still be evaluated as
qword. The issue is that there is no safe way to evaluate this with
range checking that is correct in all cases without a 128 bit integer type:
1) if you evaluate it as qword, you get a range error if count is 0 (as
above)
2) if you evaluate it as int64, then if count is high(int64)+1 you will
get a range error even though the result could be represented in int64

In this particular case, because the counter is 32 bit (which seems
quite unsafe for use with a container whose "count" property is 64 bit),
using int64 would be "correct", but it's not a systemic solution (as
shown above) and hence not something to implement in the language.


The actual code that triggered my interest was:

procedure LCLViewExtension.lclSetEnabled(AEnabled: Boolean);
var
  ns : NSArray;
  i  : integer;
  obj : NSObject;
begin
  ns := subviews;
  for i := 0 to ns.count - 1 do
  begin
    obj := NSObject(ns.objectAtIndex( i ));
    ... process obj ...
  end;
end;

I suppose i should be declared as the same type as ns.count which is NSUInteger = qword, but this will still trigger the error. You can avoid the problem by coding the loop as:

  for i := 1 to ns.count do
  begin
    obj := NSObject(ns.objectAtIndex( i-1 ));

so I suppose the real flaw is that the first item is at index 0, rather than 1, but I don't think that is a battle I am going to win.

Given how common the above bit of code is likely to be, I can't see any way of fixing this without some work in the compiler.

Colin


_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to