[fpc-devel] [Suggestion] Enumeration range-check intrinsic

Jonas Maebe jonas at freepascal.org
Sun Jul 14 14:18:10 CEST 2019


On 14/07/2019 00:12, Martok wrote:
> 
>> In Delphi's type system (and in C, C++, and C#), the valid values for an
>> enum are always all values that fit within its storage size, and that
>> storage size is fixed.
>>
>> In FPC's type system (and in Ada and Java), the valid values for an an
>> enum are only the values between the lowest and the highest declared
>> enum element (in Java it's even more strict, in that when you have
>> "enums with holes", the holes are also invalid), regardless of the
>> storage size. Moreover, this storage size can vary depending on whether
>> or not the item is in bitpacked storage.
> 
> Side note: if this was done 100% consistently (and it does make sense!), the
> PACKENUM directive would be completely useless. There is no point in being able
> to specify the storage size of an enum when it can be and is ignored at will.

It is not ignored at will. It is only ignored when an enumeration is put
in a bitpacked array/record, i.e., when the programmer explicitly
instructs the compiler to ignore it. In other cases, the requested
storage size is reserved.

However, while storage size and valid values are related (you have to
have enough storage size to store the valid values), the fact that a
particular type can store a particular bitpattern does not mean that
this bitpattern is a valid value for the type. Just take an ansistring:
you can put any bitpattern in it that fits in a PtrSInt, yet most of
them are invalid and will result in undefined behaviour.

The most common cases to specify a storage size would be alignment, and
the ability to add more valid values in the future without having to
change the layout of a data structure.

> C# and C++ do the same with explicitly sized enumerations. Who would I have to
> bribe to get that in FPC?
> 
> {$mode objfpc}
> type
>   tmyenum : Byte = (ea, eb, ec);
> 
> That would solve literally all problems we ever discussed:

It would solve nothing, and rather demonstrates the disconnect that
apparently still exists in this discussion: the ability to bitpack enums
(and hence reduce their storage size) is a mere side effect of the fact
that their valid range only goes from the lowest to the highest declared
value. You could reserve 4KB for an enum with as only valid value
"enumX" and it would not change a thing as far as the valid values or
the compiler behaviour are concerned.

The issue with a modifier or directive that would change the definition
of which values are vali for an enumerations with this modifier/within
this directive, is (besides the inconsistent low/high and range checking
behaviour from Delphi this would require, especially when subranges also
enter the picture) explained in the post I linked near the beginning of
the thread:
https://forum.lazarus.freepascal.org/index.php/topic,45507.msg322059.html#msg322059


Jonas


More information about the fpc-devel mailing list