[fpc-devel] Dangerous optimization in CASE..OF

Martok listbox at martoks-place.de
Sat Apr 21 19:06:39 CEST 2018

Am 21.04.2018 um 16:40 schrieb Alexander Grotewohl:
> To be honest I agree with what he's saying. We're bending enums to do 
> things normal people just wouldn't (and shouldn't) do.
No, we don't.

There are two semantically different sorts of enums: if you want an enum to
contain only the named elements and nothing else, just use a simple enum without
assigned values. That tells the compiler that you don't really care about
numerical values (except that they are ordinal), the named atoms matter to you.
That implies that the in-memory storage may be opaque.
This is the sort of Enums languages like Ada or Oberon have, and that we inherit
from ISO and TP modes (although they were explicitly documented in TP as
internally being the second type!).

Using assigned values tells the compiler that you *do* care about the ordinal
values. This means that we now need a specific host-type behind it (one that
contains at least all the integers you assigned). Delphi and FPC use a subrange
of the type indicated by $PACKENUM (like a minimum envelope), C-Style languages
use one of the basic integer types as that host-type (because they don't have
subranges). In any case, all values of the host-type are now valid values of the
enum, not just those that have names.
You might think of it like that:
  TProgrammerType = (tpJava=2, tpVisualC=4, tpDelphi=100,
                     tpClang=101, tpVB=255);
could be roughly rewritten as:
  TProgrammerType = record
  public type
    OrdinalType = 2..255;   // sizeof(OrdinalType) := $PACKENUM
  public const
    tpJava    = OrdinalType(2);
    tpVisualC = OrdinalType(4);
    tpDelphi  = OrdinalType(100);
    tpClang   = OrdinalType(101);
    tpVB      = OrdinalType(255);
You'll notice that if you compile that code normally,
sizeof(TProgrammerType.OrdinalType) would be 1. The storage requirement is
enforced separately from the formal type system, which is essentially the issue
at the very root of this rather long and windy thread.
This would look a bit more obvious in C#, where you might write:
  enum ProgrammerType : ushort = {tpJava=2, tpVisualC=4, tpDelphi=100,
                     tpClang=101, tpVB=255};
This syntax makes it very clear that ProgrammerType is a redefinition of ushort,
with some typed constants. The literal translation to plug in to the code above
could be
  public type
    OrdinalType = type Word;
Otherwise this is the same.

I hope this clears things up a bit.


More information about the fpc-devel mailing list