Lazarus

Free Pascal => General => Topic started by: 440bx on October 17, 2021, 06:03:37 am

Title: size of a range
Post by: 440bx on October 17, 2021, 06:03:37 am
Hello,

I wanted to define a range and have the sizeof the range be the size of a DWORD. I tried defining the range as follows:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE       CONSOLE}
  2.  
  3. {$TYPEDADDRESS  ON}
  4.  
  5. {$LONGSTRINGS   OFF}
  6.  
  7. { --------------------------------------------------------------------------- }
  8.  
  9.  
  10. program _RangeSize;
  11.  
  12. uses
  13.   Windows
  14.   ;
  15.  
  16.  
  17.  
  18. const
  19.   L = DWORD(1);
  20.   H = DWORD(100);
  21.  
  22. type
  23.   { I want the size of this type to be sizeof(DWORD) = 4                      }
  24.  
  25.   TRANGE = DWORD(L)..DWORD(H);
  26.  
  27. begin
  28.   writeln;
  29.   writeln;
  30.  
  31.   writeln('  sizeof(TRANGE) : ', sizeof(TRANGE)); { not sizeof(DWORD) as desired }
  32.  
  33.   writeln;
  34.   writeln;
  35.   writeln('press ENTER/RETURN to end this program');
  36.   readln;
  37. end.  
In the above program, in spite of casting the constants as DWORDs, the size of TRANGE is reported as 1 instead of 4.

Is there some way of defining the range to have the compiler consider it a DWORD ?

Thank you for your help.
Title: Re: size of a range
Post by: ASerge on October 17, 2021, 07:50:40 am
Now FPC uses the maximum value of one of the subrange boundaries to select the base type, but I didn't find this in the documentation.
Example:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3.  
  4. type
  5.   TSubrange = High(UInt32)-1..High(UInt32);
  6. begin
  7.   Writeln(SizeOf(TSubrange));
  8. end.
Will print 4.

But that may change. For example, for compatibility with Delphi, where the code above prints 1 and documented in Integer Subrange Types (https://docwiki.embarcadero.com/RADStudio/Sydney/en/Internal_Data_Formats_(Delphi)#Integer_Subrange_Types).
Title: Re: size of a range
Post by: 440bx on October 17, 2021, 08:59:19 am
Thank you Serge.

If I understood you correctly, it is not possible then to have a small range, e.g, 1..100, use a DWORD.  It will use the smallest type that can encompass the range (in that case, byte.)

Did I get it right ?
Title: Re: size of a range
Post by: Thaddy on October 17, 2021, 10:15:05 am
FreePascal looks if a range can be expressed as byte, word, dword.
Maybe this helps.
sizeof(DWORD(TRANGE)));
Title: Re: size of a range
Post by: marcov on October 17, 2021, 10:49:12 am
ftp://
Thank you Serge.

If I understood you correctly, it is not possible then to have a small range, e.g, 1..100, use a DWORD. 

I thought maybe packenum, but seems range doesn't adhere to it.

https://www.freepascal.org/docs-html/prog/progsu59.html
Title: Re: size of a range
Post by: ASerge on October 17, 2021, 12:01:35 pm
If I understood you correctly, it is not possible then to have a small range, e.g, 1..100, use a DWORD.  It will use the smallest type that can encompass the range (in that case, byte.)
Did I get it right ?
Yes. Moreover, even with large boundaries, it may be unreliable, because it is not specified in the documentation.
Title: Re: size of a range
Post by: Kays on October 17, 2021, 12:31:44 pm
Is there some way of defining the range to have the compiler consider it a DWORD ?
The FPC is very reluctant to make reservations for memory that will, per definition, always stay zero. A possible workaround is to wrap your range in a record:
Code: Pascal  [Select][+][-]
  1. type
  2.         range = record
  3.                         {$ifDef FPC_big_endian}
  4.                                 dummy: array[1..3] of Byte;
  5.                         {$endIf}
  6.                         value: 1..100;
  7.                         {$ifDef FPC_little_endian}
  8.                                 dummy: array[1..3] of Byte;
  9.                         {$endIf}
  10.                 end;
  11.         {$if sizeOf(range) <> sizeOf(dWord)}
  12.                 {$fatal range size mismatch}
  13.         {$endIf}
This is of course super inconvenient since now you’ll always have to specify the field designator .value, and I’m not even sure whether I did the Endian precautions correctly. :'(
Title: Re: size of a range
Post by: 440bx on October 17, 2021, 02:03:30 pm
Thank you all for your help.  Much appreciated.
TinyPortal © 2005-2018