Recent

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

fcu

  • Full Member
  • ***
  • Posts: 123
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: 6944
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: 6321
  • 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: 18729
  • To Europe: simply sell USA bonds: dollar collapses
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 »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

PascalDragon

  • Hero Member
  • *****
  • Posts: 6321
  • 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