Recent

Author Topic: Enumeration variable  (Read 1158 times)

440bx

  • Hero Member
  • *****
  • Posts: 5085
Enumeration variable
« on: April 26, 2024, 04:42:31 am »
Hello,

I wanted to initialize an enumeration variable with an invalid value but the compiler (v3.2.2) didn't like my attempt.  I tried the following:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. {$define USE_ABSOLUTE}
  4.  
  5. program _Enumerations;
  6.  
  7. type
  8.   TENUM = (e1, e2, e3);
  9.  
  10. var
  11.   {$ifndef USE_ABSOLUTE}
  12.     Enum       : TENUM = TENUM(-1);       { it won't accept this }
  13.   {$endif}
  14.  
  15.   {$ifdef USE_ABSOLUTE}
  16.     HighValues : DWORD = DWORD(-1);
  17.     Enum       : TENUM absolute HighValues;
  18.   {$endif}
  19.  
  20.  
  21.   Enum2      : TENUM;
  22.  
  23. begin
  24.   Enum2 := TENUM(-1);     { but it accepts this    }
  25.  
  26.   {$ifdef USE_ABSOLUTE}
  27.     inc(HighValues);      { needs to be referenced }
  28.   {$endif}
  29.  
  30.   readln;
  31. end.                          
It will _not_ accept the declaration in line 12.  It does accept the "equivalent" code in line 24.

"Absolute" can be used as a workaround (lines 16 and 17) but, I'd like to have, if it exists, a simpler way, something more along the lines of line 12 but acceptable to the compiler. 

That's my question: is there some fairly simple way of making line 12 acceptable to the compiler ?

Thank you for your help.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 4165
Re: Enumeration variable
« Reply #1 on: April 26, 2024, 06:08:08 am »
That's my question: is there some fairly simple way of making line 12 acceptable to the compiler ?
Make the -1 a part of the type ?

Code: Pascal  [Select][+][-]
  1. type
  2.   TENUM = (invalid=-1, e1, e2, e3);
  3. var
  4.   {$ifndef USE_ABSOLUTE}
  5.     Enum       : TENUM = invalid;
  6.   {$endif}
  7.  

btw and fwiw this is typical for c code: using (positive) enums then use -1 to indicate that the enum was invalid (mostly done when returning result codes) thus it is not wise to translate c-enums to Pascal enums especially since c-code has the tendency to skip a few numbers as well (though that can (now) be done in/with FPC as well).
Today is tomorrow's yesterday.

Thaddy

  • Hero Member
  • *****
  • Posts: 16672
  • Kallstadt seems a good place to evict Trump to.
Re: Enumeration variable
« Reply #2 on: April 26, 2024, 06:22:04 am »
Turn range checks off for the enum type or var for which you want to allow an invalid value:
Code: Pascal  [Select][+][-]
  1. type
  2.  TEnum = (aa,bb,cc);
  3. var
  4. {$push}{$R-}{$warn 4110 off}
  5.   e:TEnum = TEnum(-1);
  6. {$pop}
  7. begin
  8.   // compiles clean, no error or warning
  9.   writeln(ord(e));
  10. end.

In its simplest form just {$R-} at the top of the sourcecode is enough.
« Last Edit: April 26, 2024, 06:49:24 am by Thaddy »
But I am sure they don't want the Trumps back...

440bx

  • Hero Member
  • *****
  • Posts: 5085
Re: Enumeration variable
« Reply #3 on: April 26, 2024, 06:48:59 am »
Make the -1 a part of the type ?
That's the reasonable thing to do but, unfortunately, it would cause a lot of problems (there are already a number of things indexed using that enumeration, adding a -1 is disruptive.)

btw and fwiw this is typical for c code: using (positive) enums then use -1 to indicate that the enum was invalid (mostly done when returning result codes) thus it is not wise to translate c-enums to Pascal enums especially since c-code has the tendency to skip a few numbers as well (though that can (now) be done in/with FPC as well).
That's what it is, the actual code is a port from C.  The C code doesn't declare an "invalid" element/constant because it doesn't need it but, I extended the functionality and the extension needs an invalid value indicator.

Looks like I'll have to initialize the variable in the code instead of the declaration.

Thank you, I appreciate the help.




@Thaddy,

I tried your suggestion and the compiler still emitted an error.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16672
  • Kallstadt seems a good place to evict Trump to.
Re: Enumeration variable
« Reply #4 on: April 26, 2024, 06:51:41 am »
Strange, after my edit this gives me no errors or warning:
Code: Pascal  [Select][+][-]
  1. type
  2.  TEnum = (aa,bb,cc);
  3. var
  4. {$push}{$R-}{$warn 4110 off}
  5.   e:TEnum = TEnum(-1);
  6. {$pop}
  7. begin
  8.   writeln(ord(e));
  9. end.
note I moved r- to the var. This program prints -1
But I am sure they don't want the Trumps back...

440bx

  • Hero Member
  • *****
  • Posts: 5085
Re: Enumeration variable
« Reply #5 on: April 26, 2024, 07:00:36 am »
Strange, after my edit this gives me no errors or warning:
I copied and pasted your code.  IOW, I attempted to compile a verbatim copy of your code and the compiler refused it.

Any ideas why ?
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

nanobit

  • Full Member
  • ***
  • Posts: 168
Re: Enumeration variable
« Reply #6 on: April 26, 2024, 07:09:59 am »
Code: Pascal  [Select][+][-]
  1. type
  2.   TENUM = (e1, e2, e3);
  3. var
  4.     Enum       : TENUM = TENUM(-1);       { it won't accept this }
  5.  

Operations on this enum will have undefined behavior (UB) in FPC.
There exists a detailed note (in zip archive) about this.

Thaddy

  • Hero Member
  • *****
  • Posts: 16672
  • Kallstadt seems a good place to evict Trump to.
Re: Enumeration variable
« Reply #7 on: April 26, 2024, 07:10:29 am »
Yes, I have an idea why: if I compile on linux with 3.2.2 I also get the error. If I compile with trunk on windows or linux the error disappears.
But I am sure they don't want the Trumps back...

440bx

  • Hero Member
  • *****
  • Posts: 5085
Re: Enumeration variable
« Reply #8 on: April 26, 2024, 07:47:40 am »
Operations on this enum will have undefined behavior (UB) in FPC.
There exists a detailed note (in zip archive) about this.
Thank you for the document.  Gave it a quick read and fortunately my code should not be affected because the invalid value is only used as a flag/sentinel and tested for equality/inequality against other enum values in if statements.  I think that should be safe.




Yes, I have an idea why: if I compile on linux with 3.2.2 I also get the error. If I compile with trunk on windows or linux the error disappears.
That does explain it.  I stay away from the trunk version of the compiler.  I'll stick with stable even if it means I lose some minor features I could use.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12121
  • FPC developer.
Re: Enumeration variable
« Reply #9 on: April 26, 2024, 07:54:00 am »
Enum is not an integer as that document says. All Pascal etc says is that it is an oridinal type, nothing more.

Avinash

  • Full Member
  • ***
  • Posts: 123
Re: Enumeration variable
« Reply #10 on: April 26, 2024, 08:49:19 am »
Code: Pascal  [Select][+][-]
  1. type TENUM = (e1=1, e2, e3);
  2.  
  3. var  Enum: TENUM;
  4.  
  5. begin
  6.   WriteLn(Ord(Enum));   { 0 }
  7.  
  8.   Enum := E1;
  9.   WriteLn(Ord(Enum));   { 1 }
  10.   Enum := E2;
  11.   WriteLn(Ord(Enum));   { 2 }
  12.   Enum := E3;
  13.   WriteLn(Ord(Enum));   { 3 }
  14. end.

 

TinyPortal © 2005-2018