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

Ondrej Pokorny lazarus at kluug.net
Fri Jul 5 10:36:36 CEST 2019


On 05.07.2019 09:57, Michael Van Canneyt wrote:
> On Fri, 5 Jul 2019, Ondrej Pokorny wrote:
>> On 05.07.2019 09:04, Michael Van Canneyt wrote:
>>> In this, I would definitely exclude enumerateds that have explicitly 
>>> assigned
>>> values: str does not handle them, getenumename etc. also do not work:
>>> They are in effect simply integer constants. (if I had my way I would
>>> even remove them from the language).
>>>
>>> So using the above construct on such an enum can lead to a compiler 
>>> error,
>>> because the compiler cannot check anyway: better a clear error than 
>>> undefined
>>> behaviour.
>>
>> On the contrary, the compiler can check enums with holes with no 
>> problem at all. They have valid low/end boundaries. And the holes in 
>> between are valid values as well.
>
> Eh ? Not in my book, if the compiler allows that it is simply wrong IMO.
>
> An enumerated enumerates the allowed values: no holes allowed.
>
> What you describe, I would name a range, not an enumeration.
>
>> So there is no actual need or benefit to disable this feature for 
>> enums with holes.
>
> See above.
>
> The way I read jonas' argument:
>
> TMyEnum = (one, two=3,three);
>
> A:=TMyEnum(1) ;
>
> will pass unchallenged.
>
> I don't see the point of allowing this. for me, "A" has an invalid value.
>
> Note: This is my opinion, it may be at odds with what the compiler 
> actually
> implements :)

Read: 
http://docwiki.embarcadero.com/RADStudio/Rio/en/Simple_Types_(Delphi)#Enumerated_Types_with_Explicitly_Assigned_Ordinality


>> +++
>>
>> Btw. why nobody commented on my latest suggestion in 
>> https://lists.freepascal.org/pipermail/fpc-devel/2019-July/041499.html ?
>> IMO this is a valid solution for both sides.
>
> What part exactly ? The additional range check for a case in case of 
> range checking ?

Yes.


> I don't see why you need it, since in case range checking is enabled, 
> the assignment of the variable should already have ensured that there 
> are only valid values in it.

The compiler can never catch all kinds of assignments and do range 
checking on them (e.g. FillChar, Read, pointer-writes, etc. etc.). So a 
range check when accessing a value is needed.

It's the same reasons FPC has fpc_check_object and falls into the same 
philosophy.

If I take your statement "in case range checking is enabled, the 
assignment of the variable should already have ensured that there are 
only valid values in it." to the extreme, it implies that the creation 
of an object with a subrange value always ends up with a range check error:

program Project1;
type
   TMyClass = class
   private
     FSubRange: 2..4;
   end;
   TMyRecord = record
     SubRange: 2..4;
   end;
   PMyRecord = ^TMyRecord;
var
   C: TMyClass;
   R: PMyRecord;
begin
   C := TMyClass.Create; // << range check error here
   R := AllocMem(SizeOf(TMyRecord)); // << range check error here
end.

Ondrej



More information about the fpc-devel mailing list