Recent

Author Topic: Enumeration symbols values limits  (Read 6227 times)

fcu

  • Full Member
  • ***
  • Posts: 131
Enumeration symbols values limits
« on: January 07, 2022, 10:23:08 pm »
Hi
this code works fine with fpc 3.2 but not with 3.3 (trunk)
is there a workaround for this error ?
Code: Pascal  [Select][+][-]
  1.  type
  2.   TD3DDevType = (
  3.     D3DDEVTYPE_HAL = 1,
  4.     D3DDEVTYPE_REF = 2,
  5.     D3DDEVTYPE_SW = 3,
  6.     D3DDEVTYPE_NULLREF = 4,
  7.     D3DDEVTYPE_FORCE_DWORD = $ffffffff // Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1
  8.   );      
  9.  

rvk

  • Hero Member
  • *****
  • Posts: 7064
Re: Enumeration symbols values limits
« Reply #1 on: January 08, 2022, 12:21:52 am »
And are you sure ord(D3DDEVTYPE_FORCE_DWORD) evaluated back to $ffffffff in the older version??

From https://wiki.freepascal.org/User_Changes_Trunk

Quote
Explicit values for enumeration types are limited to low(longint) ... high(longint)
  • Old behavior: The compiler accepted every integer value as explicit enumeration value. The value was silently reduced to the longint range if it fell outside of that range
  • New behavior: The compiler throws an error (FPC mode) or a warning (Delphi mode) if an explicit enumeration value lies outside the longint range.
  • Reason: Type TEnum = (a = $ffffffff); resulted in an enum with size 1 instead of 4 as would be expected, because $ffffffff was interpreted as "-1".
  • Remedy: Add Longint typecasts to values outside the valid range of a Longint.
So you could do this:
Quote
Remedy: Add Longint typecasts to values outside the valid range of a Longint.

This seems to compile:
Code: Pascal  [Select][+][-]
  1. type
  2.  TD3DDevType = (
  3.    D3DDEVTYPE_HAL = 1,
  4.    D3DDEVTYPE_REF = 2,
  5.    D3DDEVTYPE_SW = 3,
  6.    D3DDEVTYPE_NULLREF = 4,
  7.    D3DDEVTYPE_FORCE_DWORD = LongInt($ffffffff) // Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1
  8.  );

(Not sure if it gives the desired result in your code.)

PascalDragon

  • Hero Member
  • *****
  • Posts: 6421
  • Compiler Developer
Re: Enumeration symbols values limits
« Reply #2 on: January 08, 2022, 12:01:42 pm »
(Not sure if it gives the desired result in your code.)

Yes, it does. Another way - as D3DDEVTYPE_FORCE_DWORD is clearly intended to only ensure the correct size of the enum - is to use MinEnumSize:

Code: Pascal  [Select][+][-]
  1. program tenum;
  2.  
  3. {$mode objfpc}
  4.  
  5. type
  6.  TD3DDevType = (
  7.    D3DDEVTYPE_HAL = 1,
  8.    D3DDEVTYPE_REF = 2,
  9.    D3DDEVTYPE_SW = 3,
  10.    D3DDEVTYPE_NULLREF = 4,
  11.    D3DDEVTYPE_FORCE_DWORD = LongInt($ffffffff)
  12.  );
  13.  
  14.  {$Push}
  15.  {$MinEnumSize 4}
  16.  TD3DDevType2 = (
  17.    D3DDEVTYPE2_HAL = 1,
  18.    D3DDEVTYPE2_REF = 2,
  19.    D3DDEVTYPE2_SW = 3,
  20.    D3DDEVTYPE2_NULLREF = 4
  21.  );
  22.  {$Pop}
  23.  
  24.  
  25. begin
  26.   Writeln(SizeOf(TD3DDevType)); // will write 4
  27.   Writeln(SizeOf(TD3DDevType2)); // will write 4 as well
  28. end.

Yes, that means that D3DDEVTYPE_FORCE_DWORD would not be available, but it isn't a “valid” value for the API anyway.

Thaddy

  • Hero Member
  • *****
  • Posts: 19612
  • Glad to be alive.
Re: Enumeration symbols values limits
« Reply #3 on: January 09, 2022, 03:36:57 pm »
Working with bits on all integer types (signed or not) is supported in an easy way by using the helpers from sysutils. This does not fully apply to Pascal enumerations, though.
See syshelph.inc

So if you need the bits for an external API that should not be very difficult.
« Last Edit: January 09, 2022, 03:40:23 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

PascalDragon

  • Hero Member
  • *****
  • Posts: 6421
  • Compiler Developer
Re: Enumeration symbols values limits
« Reply #4 on: January 10, 2022, 01:46:51 pm »
it would be nice if one could use unsigned values in there so one could use bit fields in a DWORD or word for example to represent closely to what you see in many of API's and third party libs and C code etc..

No. Enumeration types are signed. This has always been this way and it will stay this way and it is also Delphi compatible.

Working with bits on all integer types (signed or not) is supported in an easy way by using the helpers from sysutils. This does not fully apply to Pascal enumerations, though.
See syshelph.inc

So if you need the bits for an external API that should not be very difficult.

This is not about working with bits, so please don't mix in unrelated topics.

 

TinyPortal © 2005-2018