Recent

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

tetrastes

  • Hero Member
  • *****
  • Posts: 733
Why not
Code: Pascal  [Select][+][-]
  1. D2D1_PROPERTY_CLSID = int32($80000000),
  2. etc...

And int32($FFFFFFFF) = -1, not high(int32) nor low(int32).

440bx

  • Hero Member
  • *****
  • Posts: 6025
Why not
Code: Pascal  [Select][+][-]
  1. D2D1_PROPERTY_CLSID = int32($80000000),
That works but strictly speaking the cast is superfluous.

Also, as previously mentioned, the value $FFFFFFFF which C uses to force the size is unnecessary (superfluous again) in FPC.

All that stuff is just useless noise.

Simple and easy: $Z4 and list the hex values that may actually be used by the code.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

tetrastes

  • Hero Member
  • *****
  • Posts: 733
Why not
Code: Pascal  [Select][+][-]
  1. D2D1_PROPERTY_CLSID = int32($80000000),
That works but strictly speaking the cast is superfluous.

As I understand OP, without cast it isn't compiled in trunk.

440bx

  • Hero Member
  • *****
  • Posts: 6025
I don't use the trunk version but, from what he described the problem is using $FFFFFFFF in the presence of decimal numbers.

Based on the error he gets, the reason is because in the presence of decimal numbers the interpretation of $FFFFFFFF is as an unsigned value which causes a range error because unsigned $FFFFFFFF is a value that does not fit in the range low(int32)..high(int32).

if there are no decimal numbers then $FFFFFFFF will be interpreted as -1 which is perfectly fine and that is what the typecast you suggested does. 

Succinctly, needing the typecast is a symptom of a badly defined type.  Either use decimals or use hexadecimals but, don't mix them because when mixed some patterns will be interpreted differently in the presence of decimal numbers.

$FFFFFFFF as unsigned is: 4294967295 which is definitely outside the range of low(int32)..high(int32) hence the error.  The cast makes it -1 which is in the range.   The cast is unnecessary when the type definition is clean, that is, all hex or all decimal, instead of a dirty mix.


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

tetrastes

  • Hero Member
  • *****
  • Posts: 733
His problem is not in $FFFFFFFF only:

However I have to fix now these values
Code: Pascal  [Select][+][-]
  1.   TD2D1_PROPERTY = (
  2.       D2D1_PROPERTY_CLSID = $80000000,
  3.       D2D1_PROPERTY_DISPLAYNAME = $80000001,
  4.       D2D1_PROPERTY_AUTHOR = $80000002,
  5.       D2D1_PROPERTY_CATEGORY = $80000003,
  6.       D2D1_PROPERTY_DESCRIPTION = $80000004,
  7.       D2D1_PROPERTY_INPUTS = $80000005,
  8.       D2D1_PROPERTY_CACHED = $80000006,
  9.       D2D1_PROPERTY_PRECISION = $80000007,
  10.       D2D1_PROPERTY_MIN_INPUTS = $80000008,
  11.       D2D1_PROPERTY_MAX_INPUTS = $80000009,
  12.       D2D1_PROPERTY_FORCE_DWORD = LOW(Int32)
  13.   );
  14.  

Cause $80000001 which starts with $8xxxxxxx is still too big number for the enum.

440bx

  • Hero Member
  • *****
  • Posts: 6025
The definition you posted there should compile without problems. Try compiling it.

The only "problem" in that definition is that the values are not in ascending order and the compiler will issue a note about that but, that's no big deal (though it wouldn't take much to clean that up.)

As I stated in a previous post, the low(int32) is not necessary either.

All the problems in the definition, without exception, stem from including things that are either unnecessary or don't belong in the definition at all.  All that's needed is {$Z4} and define the enumeration using one and only one type of numbers, either hex or decimal but _not_ a mix because that can cause range errors.

He had a problem when he included decimal numbers mixed with hex in that definition.

Again, there is absolutely no need for "low(int32") and/or typecasting anything to "int32" if the definition is _clean_ as it should be.  i.e, use {$Z4} and don't mix hex and decimals.  That's it.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

tetrastes

  • Hero Member
  • *****
  • Posts: 733
It compiles with fpc 3.2.2, but OP says that it is not compiled with trunk. This is the issue of all this stuff:

Hi,

I have some DirectX related code which compiles fine with FPC 3.2.2.
Now I switched to the latest FPC and Lazarus trunk 3.3.1 and it does not compile any more.

The error is
Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1

And of course you can mix decimal and hex numbers, compiler is quite happy with both:
Code: Pascal  [Select][+][-]
  1. type
  2.  TSOME_ENUM =
  3.  (
  4.   tse1 = $80000000,
  5.   tse2 = -$80000000,
  6.   tse3 = -2147483648,
  7.   tse4 = 2147483648,
  8.   tse5 = $80000001,
  9.   tse6 = -$80000001,
  10.   tse7 = -2147483647,
  11.   tse8 = $FFFFFFFF,
  12.   tse9 = -$FFFFFFFF,
  13.   tseA = -1   //tse10 = -1
  14.  );

results in (compiled with fpc 3.2.4-rc1)

Code: ASM  [Select][+][-]
  1. RTTI_$P$PROGRAM_$$_TSOME_ENUM_s2o:
  2.         .long   10,-2147483648
  3.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+29
  4.         .long   -2147483648
  5.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+34
  6.         .long   -2147483648
  7.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+39
  8.         .long   -2147483648
  9.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+44
  10.         .long   -2147483647
  11.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+49
  12.         .long   2147483647
  13.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+54
  14.         .long   -2147483647
  15.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+59
  16.         .long   -1
  17.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+64
  18.         .long   1
  19.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+69
  20.         .long   -1
  21.         .quad   RTTI_$P$PROGRAM_$$_TSOME_ENUM+74
  22.  

EDIT: changed tse10 to tseA, since tse10 becomes second item in enum (after tse1), which may cause confusion.
« Last Edit: December 15, 2025, 12:22:57 am by tetrastes »

440bx

  • Hero Member
  • *****
  • Posts: 6025
And of course you can mix decimal and hex numbers, compiler is quite happy with both:
I didn't say you couldn't mix them, I said you _shouldn't_.  The reason is because when you mix hex and decimal the compiler interprets some hex sequences, such as $FFFFFFFF differently and, THAT is what causes the range errors.

in the presence of decimal values, $FFFFFFFF is interpreted by the compiler as an unsigned integer which in an enumeration causes an error.

Again, use hex numbers or use decimal numbers, _don't_ mix them because mixing them causes the compiler to change the interpretation of some hex sequences, such as $FFFFFFFF

Keep it simple, no typecasts needed, no forcing the size by using values that are not used in the code (noise) and lastly, if  you need some specific size, there is a directive for it: {$Z4}, that's what it's there for, to spare the programmer from adding unnecessary values to the enumeration to force its size.

The last thing Pascal needs is to import garbage from C, which is what that $FFFFFFFF is.

In C, what they should have done is implement a pragma to control the enum size instead of relying on creating unused values that force the size.   Fortunately, Pascal didn't go that route and the last thing Pascal programmers should do is emulate C's deficiencies.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Lauriet

  • New Member
  • *
  • Posts: 33
Am I being nieve here?
Whats wrong with
Code: Pascal  [Select][+][-]
  1. type
  2.   EnumType = (  D2D1_PROPERTY_CLSID,   D2D1_PROPERTY_DISPLAYNAME,  D2D1_PROPERTY_AUTHOR,
  3.                         D2D1_PROPERTY_CATEGORY,  D2D1_PROPERTY_DESCRIPTION,  D2D1_PROPERTY_INPUTS,
  4.                         D2D1_PROPERTY_CACHED,  D2D1_PROPERTY_PRECISION,  D2D1_PROPERTY_MIN_INPUTS,
  5.                         D2D1_PROPERTY_MAX_INPUTS,  D2D1_PROPERTY_FORCE_DWORD);
  6.  



That's Pascal.

I don't know what you are doing with these but there are plenty of standard Pascal ways of using them.
eg: if ($80000000 + Ord(EnumMember) = whatever then

But why does it need to be Enumerated instead of Constants ???





440bx

  • Hero Member
  • *****
  • Posts: 6025
In the definition you proposed, the identifiers don't have the values they are supposed to have. e.g, in your definition the value of D2D1_PROPERTY_CLSID is 0 instead of $80000000

There are reasons to create an enumerated type, the reasons vary depending on the purpose of the enumeration but, among them:

1. an enumerated type, unlike a constant, is a type, therefore each identifier has the size of the enumeration.  This can be very important depending on how the enumeration is used.

2. an enumerated type without gaps between its member can be used in a "for in" statement.  You cannot do that with constants.

3. an enumerated type formalizes that the group of constants belong together.  Stand alone constant give no indication of how they should be or are group (if they are grouped at all.)

4. an enumerated type is a very convenient mechanism to ensure a group of constants have consecutive values (the compiler assigns the values for you - though you can override that, which allows you to define multiple ranges in an enumeration - all neatly grouped in a type instead of a jumble of constants.

Those off the top of my head, I'm pretty sure there are other reasons too but, that should suffice.

as an example of 3. consider the function (in C):
Code: C  [Select][+][-]
  1. __kernel_entry NTSTATUS NtQueryInformationThread(
  2.   [in]            HANDLE          ThreadHandle,
  3.   [in]            THREADINFOCLASS ThreadInformationClass,
  4.   [in, out]       PVOID           ThreadInformation,
  5.   [in]            ULONG           ThreadInformationLength,
  6.   [out, optional] PULONG          ReturnLength
  7. );
  8.  
Since the ThreadInformationClass is of type THREADINFOCLASS that allows the compiler to enforce that the value of the parameter be a member of the type.  If the enumeration did not exist, the compiler could not do any checking thus allowing the programmer to pass a wrong value, necessitating using a debugger to figure out that the value passed is not valid.

That should answer your question: "But why does it need to be Enumerated instead of Constants ???"
Now you know (or at least should know.)

Succinctly, plenty of good reasons to define enumerated types instead of constants.

HTH.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

tetrastes

  • Hero Member
  • *****
  • Posts: 733
And of course you can mix decimal and hex numbers, compiler is quite happy with both:
I didn't say you couldn't mix them, I said you _shouldn't_.  The reason is because when you mix hex and decimal the compiler interprets some hex sequences, such as $FFFFFFFF differently and, THAT is what causes the range errors.

in the presence of decimal values, $FFFFFFFF is interpreted by the compiler as an unsigned integer which in an enumeration causes an error.

Again, use hex numbers or use decimal numbers, _don't_ mix them because mixing them causes the compiler to change the interpretation of some hex sequences, such as $FFFFFFFF

These are your fantasies. If it was so, it would be a serious bug.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. type
  4.  TSOME_ENUM =
  5.  (
  6.   tse1 = $80000000,
  7.   //tse2 = -$80000000,
  8.   //tse3 = -2147483648,
  9.   //tse4 = 2147483648,
  10.   tse5 = $80000001,
  11.   //tse6 = -$80000001,
  12.   //tse7 = -2147483647,
  13.   tse8 = $FFFFFFFF     //,
  14.   //tse9 = -$FFFFFFFF,
  15.   //tseA = -1  
  16.  );
produces
Code: ASM  [Select][+][-]
  1. RTTI_$P$PROJECT1_$$_TSOME_ENUM_s2o:
  2.         .long   3,-2147483648
  3.         .quad   RTTI_$P$PROJECT1_$$_TSOME_ENUM+29
  4.         .long   -2147483647
  5.         .quad   RTTI_$P$PROJECT1_$$_TSOME_ENUM+34
  6.         .long   -1
  7.         .quad   RTTI_$P$PROJECT1_$$_TSOME_ENUM+39

Compare with my previous post. Hex numbers are interpreted identically, mixed with decimal or not. Why do you not check it before writing?

Keep it simple, no typecasts needed, no forcing the size by using values that are not used in the code (noise) and lastly, if  you need some specific size, there is a directive for it: {$Z4}, that's what it's there for, to spare the programmer from adding unnecessary values to the enumeration to force its size.

Say it to fpc developers. In trunk the above code does not compile, with or without {$Z4}, as OP had written:

Target OS: Win64 for x64
Compiling project1.lpr
project1.lpr(6,19) Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1
project1.lpr(10,19) Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1
project1.lpr(16,2) Error: Enumeration symbols can only have values in the range of -2^31 to 2^31-1
project1.lpr(23) Fatal: There were 3 errors compiling module, stopping
Fatal: Compilation aborted

440bx

  • Hero Member
  • *****
  • Posts: 6025
Obviously, you are impervious to understanding. 

Good luck.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

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.

paweld

  • Hero Member
  • *****
  • Posts: 1561
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
Best regards / Pozdrawiam
paweld

440bx

  • Hero Member
  • *****
  • Posts: 6025
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.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018