Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2002-12

Re: fpc-pascal digest, Vol 1 #1610 - 12 msgs

9 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author
Finally, in response to the original poster: "for x := 0 to -1 do..." will indeed not exexcute any iteration under FPC.

Right now, I have

{$MODE OBJFPC}
destructor tScreen.Destroy;
var
  I : tUnsigned16;
  W : tWindow;
begin
  WriteLn('Count: ' + IntToStr(myWindows.Count));
  for I := 0 to myWindows.Count - 1 do begin
    W := tWindow(myWindows[I]);
    W.Close;
  end;
end;

in the code and the loop does in fact execute, even though myWindows.Count is zero. The error message I get when I run this code is:

Count: 0
An unhandled exception occurred at 0x00405DA9 :
List index exceeds bounds (0)
0x00405DA9

Tim

Reply by email

Jonas Maebe
to Unknown author
Show quoted text 5 lines
{$MODE OBJFPC} destructor tScreen.Destroy; var I : tUnsigned16;

Here is your problem! Your counter variable is unsigned, so all expressions in your for-statement are also converted to unsigned. Change this to "I : Integer" and it will work fine. You can also turn on range checking and then you will get a range check error in the loop initialization code.

Jonas

Reply by email

Unknown author
I : tUnsigned16;

Um, unsigned... this will always equate to 0 if the count is 0 because an *unsigned* number can _only_ hold positive numbers (0..n, *not* -n..(n -1)). So 0 -1 can only be 0 because 0 is the smallest number the variable can hold. For i := 0 to 0 do ; will indeed execute one itteration, and cause an access violation if you attempt to access memory that was no allocated (as you will) with your pointer.

Change it to a signed type (longint, integer, smallint, int64, etc) and you will no longer crash, I guess.

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Jonas Maebe
to Unknown author
Show quoted text 6 lines
Um, unsigned... this will always equate to 0 if the count is 0 because an *unsigned* number can _only_ hold positive numbers (0..n, *not* -n..(n -1)). So 0 -1 can only be 0 because 0 is the smallest number the variable can hold.

No, a type conversion between ordinal types does not change one bit pattern into another. -1 is a bit pattern that only contains 1-bits, so when you convert that to an unsigned type, it still contains only 1-bits and as such becomes the highest value that that unsigned type can represent (65535 in case of an unsigned 16 variable).

Jonas

Reply by email

Unknown author
Show quoted text 5 lines
No, a type conversion between ordinal types does not change one bit pattern into another. -1 is a bit pattern that only contains 1-bits, so when you convert that to an unsigned type, it still contains only 1-bits and as such becomes the highest value that that unsigned type can represent (65535 in case of an unsigned 16 variable).

Whatever the truth, how else does the 'list index out of bounds (0)' happen?

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Jonas Maebe
to Unknown author
Show quoted text 9 lines
> No, a type conversion between ordinal types does not change one bit > pattern into another. -1 is a bit pattern that only contains 1-bits, > so > when you convert that to an unsigned type, it still contains only > 1-bits and as such becomes the highest value that that unsigned type > can represent (65535 in case of an unsigned 16 variable). Whatever the truth, how else does the 'list index out of bounds (0)' happen?

TList.count returns -1, this is converted to a 16 bit unsigned value = 65535 -> the loop is run from 0 to 65535 (and crashes in the first iteration).

Jonas

Reply by email

Unknown author
to Jonas Maebe
Jonas Maebe wrote 17 lines
On maandag, dec 9, 2002, at 12:06 Europe/Brussels, wrote: >> No, a type conversion between ordinal types does not change one bit >> pattern into another. -1 is a bit pattern that only contains 1-bits, >> so >> when you convert that to an unsigned type, it still contains only >> 1-bits and as such becomes the highest value that that unsigned type >> can represent (65535 in case of an unsigned 16 variable). > > Whatever the truth, how else does the 'list index out of bounds (0)' > happen? TList.count returns -1, this is converted to a 16 bit unsigned value = 65535 -> the loop is run from 0 to 65535 (and crashes in the first iteration).

How can TList.count return a -1 ? Normally, this cannot happen.

Michael.

Reply by email

Jonas Maebe
to Unknown author
Show quoted text 5 lines
> TList.count returns -1, this is converted to a 16 bit unsigned value = > 65535 -> the loop is run from 0 to 65535 (and crashes in the first > iteration). How can TList.count return a -1 ? Normally, this cannot happen.

Well, the expression was:

var
   i: tunsigned16; { or something like that }
begin
   for i := 0 to (tlist_var.count - 1) do
     ...

So count returned 0, then 1 was sibstracted and the result was converted to a word...

Jonas

Reply by email

Unknown author
How can TList.count return a -1 ? Normally, this cannot happen.

I checked it out in Delphi.

var
  a: integer;
  b: cardinal;
begin
  a := 0 -1; //fine.. like we all hoped ;-)
  b := 0 -1; //will not compile... gives an error concerning bounds
  b := 0;
  b := b -1; // no error
  showmessage(  format( '%d %1:d %1:u', [a, b] )  ); // shows '-1 -1 4294967295'
end;

So Jonas is correct, in so much as the value in memory is the same, but the compiler interprets it differently for signed/unsigned types.

I think, at the end of the day, the error produces the same result whether the value is '0' or 65535... though I admit I didn't understand how FPC interprets - 1 as an unsigned value ;-)

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email