Recent

Author Topic: Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1  (Read 2493 times)

tetrastes

  • Hero Member
  • *****
  • Posts: 733
Obviously, you cannot show code to prove your fantasies.
In this case, accusing the opponent of mental disability is the best way out.
Unfortunately for you, that was not an accusation, it was the observation of a fact.

As far as code, the OP already posted code that exhibits the problem.

And the problem is that his code is compiled by stable, but isn't compile by trunk. That is you who don't understand it. Reread the first post. Install trunk and try.
And don't become the second Thaddy, please.

440bx

  • Hero Member
  • *****
  • Posts: 6025
Read the OP's message (not mine!) at: https://forum.lazarus.freepascal.org/index.php/topic,73015.msg572297.html#msg572297
Look carefully at the picture.

figure out why he is getting an error... pay particular attention to the line the compiler is complaining about.

My request to you is: don't prove Einstein's premise about infinity right.  Too many people already engage in that activity.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

tetrastes

  • Hero Member
  • *****
  • Posts: 733
Quote from: tetrastes
And of course you can mix decimal and hex numbers, compiler is quite happy with both:
Of course, it can handle both, but hex numbers it treats as unsigned.
FPC 3.2-fixes, x86_64:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}
  4.  
  5. begin
  6.   WriteLn('a: ', $80000000);
  7.   WriteLn('b: ', Int32($80000000));
  8.   ReadLn;
  9. end.
output:
Code: [Select]
a: 2147483648
b: -2147483648

Both are treated identically. For compiler this code is the same as
Code: Pascal  [Select][+][-]
  1. begin
  2.   WriteLn('a: ', 2147483648);
  3.   WriteLn('b: ', Int32(2147483648));
  4.   ReadLn;
  5. end.

And here also:  :D
Code: Pascal  [Select][+][-]
  1. begin
  2.   WriteLn('a: ', -2147483648);
  3.   WriteLn('b: ', UInt32(-2147483648));
  4.   WriteLn('a: ', -$80000000);
  5.   WriteLn('b: ', UInt32(-$80000000));
  6.   ReadLn;
  7. end.
  8.  


tetrastes

  • Hero Member
  • *****
  • Posts: 733
Read the OP's message (not mine!) at: https://forum.lazarus.freepascal.org/index.php/topic,73015.msg572297.html#msg572297
Look carefully at the picture.

figure out why he is getting an error... pay particular attention to the line the compiler is complaining about.

My request to you is: don't prove Einstein's premise about infinity right.  Too many people already engage in that activity.

He is getting an error because he is using trunk. There is no error in stable. OP clearly wrote this in the first post.
EDIT: And I checked it. With trunk and stable and fixes and 3.2.4_RC1.

My request to you is: try to compile code yourself before writing. With trunk and with stable.
« Last Edit: December 15, 2025, 12:32:53 pm by tetrastes »

nanobit

  • Full Member
  • ***
  • Posts: 183
Thank you all for the insides.
440bx, I will
- remove the FORCE_DWORD at all

Caution, you cannot simply remove range boundaries (for reserving more enum values).
With FPC (unlike Delphi), enum values have defined behavior (in operations) only for the declared range, even if the {$MINENUMSIZE } is larger. If in the future the api (dll) adds a new value (eg. $80000010), then you will get undefined behavior on this value, eg. when jumping to the else-branch of a case-statement.

In addition, FPC/Delphi does not support more than longint range.
So the two options are:  declare dword-constants
or declare enum with casting for every value: longint(number).
(casting works, but does not look good).
« Last Edit: December 15, 2025, 12:38:50 pm by nanobit »

daniel_sap

  • Full Member
  • ***
  • Posts: 115
For sure the code compiles in 3.2.2 and not in 3.3.1
I was thinking that this is some kind of improvement in FPC, though it causes me trouble. (cause I saw some other restrictive changes in 3.3.1)

But what is the exact reason not to allow the big $8xxxxxxx values in 3.3.1
May be the big/little-endian difference in different architectures.

At first glance it looks like it is just a memory with zeroes and ones,
and if $8xxxxxxx is given it should map to some Enum element.

I think also if this doesn't work in 3.3.1 a lot of ported code from C++ will not work also.

To make it simple I wrote this minimum code program which does not compile in 3.3.1 and compiles in 3.2.2

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes
  10.   { you can add units after this };
  11.  
  12. type
  13.  
  14.   {$Z4}
  15.  
  16.   TMyEnum = (
  17.     Element1 = $80000001,
  18.     Element2 = $80000002,
  19.     Element3 = $FFFFFFFF
  20.   );
  21.  
  22. var
  23.   Var1: TMyEnum;
  24.  
  25. begin
  26.   Var1 := TMyEnum.Element3;
  27.   WriteLn(Var1);
  28.   ReadLn;
  29. end.
  30.  
« Last Edit: December 15, 2025, 03:53:37 pm by daniel_sap »

nanobit

  • Full Member
  • ***
  • Posts: 183
But what is the exact reason not to allow the big $8xxxxxxx values in 3.3.1

The enum limitations are relics from the distant past.
(It would be possible to extend/modernize in this regard).
The original Pascal shortly defined: "Enumeration symbols can have values only in the range of -2^31 to 2^31-1".
Nothing about underlying types was specified, but this leads to longint and smaller integers, and disallows DWORD.

And another limitation: For the enum range (low, high) itself, Wirth essentially used the frozen enum, but he was not happy with the frozen enum, so he removed it completely in the first Oberon version. (later, due to critiques about the absence of any enum, he restored the enum again).

In the meantime, Delphi pragmatically added support for enums in API functions, thus enums became non-frozen, although the term "non-frozen" was not known at that time. And FPC kept the original frozen enum (has defined behavior in declared range only).

For DWord, you have several options:
1) DWord constants (I would use this).
2) decimal longints in enum-range (-2147483648, ..., -1, 0, ..., 2147483647);
3) typecasting in enum-range ( longint( $80000000), ..., longint($ffffffff), 0, ..., $7fffffff);
Mapping to longint enum is rather a workaround, because one has also to consider possible side effects:
Are the reserved (nameless) values still defined?  Has the value-order changed?
Example: Mapping  ($80000000,.., $ffffffff)  to range (longint( $80000000), ..., longint($ffffffff))
would preserve all reserved values and also the order, because this is (-2147483648,..,-1).
But the situation would change somewhat if the API constant declaration (DWord) adds a smaller value ( < $80000000) in the future, because in the signed enum-range the new value would be the largest enum.

daniel_sap

  • Full Member
  • ***
  • Posts: 115
Thank you, nanobit

 

TinyPortal © 2005-2018