[fpc-devel] [Suggestion] Enumeration range-check intrinsic
Martok
listbox at martoks-place.de
Sun Jul 14 15:53:46 CEST 2019
Am 14.07.2019 um 14:18 schrieb Jonas Maebe:
>> 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.
>
> In other cases, the requested storage size is reserved.
Oh please, don't troll. I know that you know that "is reserved" and "is used"
are not the same thing.
> 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.
... the only reasonable application of which is some kind of IO or an ABI that
shouldn't change, for which enums must not be used directly in the first place.
> 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
No, you couldn't. The largest ordinal type is QWORD.
> The issue with a modifier or directive that would change the definition
> of which values are valid for an enumerations with this modifier/within
> this directive, is (besides the inconsistent low/high and range checking
> behaviour from Delphi this would require,
This is easy, enums already have separate min/max and a basedef. Make the
basedef a type that can hold an orddef, modify calcsavesize and packedbitsize
accordingly, done.
Low/High will continue to provide the named range.
Arrays of such a type should not be allowed (as for enums with jumps right now)
(* although they could be without surprises, Array[tmyenum] would simply be
Array[Byte] *).
On Subranges, that's also simple and obvious. That's the beauty of it, explicit
sizes would be explicit. They are not "inherited":
tmyenum : Byte = (ea, eb, ec);
tsubenum = eb..ec;
//^ basedef=tmyenum, no explicit type, "fpc-style" enum,
// inherited symtable with ordinals $01 and $02
tsubwenum: Word = eb..ec;
//^ basedef=u16inttype, new symtable with ordinals $0001 and $0002
While the first example looks inconsistent, it is the same as what we already have:
{$PACKENUM 1}
tmyenum = (ea, eb, ec);
{$PACKENUM DEFAULT}
tsubenum = eb..ec;
tsubenum will be 4-bytes, tmyenum is 1 byte, same as with the new syntax.
tsubenum remains assignment compatible to tmyenum.
In contrast tmyenum.eb and tsubwenum.eb are not compatible, as the obviously
cannot be, since they have different _explicit_ sizes. I can't think of a
usecase for the second declaration in the first place, but getting correct
behaviour as a side effect is always a good sign.
> the post I linked near the beginning of
> the thread:
> https://forum.lazarus.freepascal.org/index.php/topic,45507.msg322059.html#msg322059
As I wrote in the last message, those points would be fully addressed by this
proposal. Choosing at declaration time is the only valid solution, all modes
will behave exactly the same once the type is defined.
Best,
Martok
More information about the fpc-devel
mailing list