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

J. Gareth Moreton gareth at moreton-family.com
Fri Jul 5 20:05:01 CEST 2019


Hey there - sorry if I'm not explaining myself too well.

My question would be this... if Value is a variable of type TEnum that 
is invalid (either because it is out of range or contains a 'hole' 
value, but more specifically the former), should "Value is TEnum" return 
True, False or an exception?  If it's an exception, then "Value is 
TEnum" will only ever return True or raise an exception if Value is of 
type TEnum.  If it returns False instead, then it's a nice and efficient 
check to see if Value is valid or not, which is the main point of 
contention around this topic... how can we reliably detect an invalid 
value and not let the program slip into an undefined state?

For Prec and Succ to return an exception if the next value is a hole, 
that will certainly be easier to program, since then the code can be 
equivalent to this:

----

function Succ(EnumVal: TEnum): TEnum; inline;
begin
   Result := TEnum(Ord(EnumVal) + 1);
   if (m_delphi in current_settings.modeswitches) and
     not (Result is TEnum) then
       raise RunTimeError201;
end;

----

Of course the code would be generated directly and not have the check 
for Delphi mode (it'll just remove the condition and exception raise 
completely) but you get the idea.

Gareth aka. Kit


On 05/07/2019 18:28, Sven Barth via fpc-devel wrote:
> Pierre Muller <pierre at freepascal.org <mailto:pierre at freepascal.org>> 
> schrieb am Fr., 5. Juli 2019, 17:51:
>
>
>
>     Le 05/07/2019 à 17:42, J. Gareth Moreton a écrit :
>     >
>     > On 05/07/2019 15:51, Pierre Muller wrote:
>     >> Just one point from current compiler implementation:
>     >>
>     >> in trunk/fpcsrc/compiler/ninl.pas (around line 3180)
>     >>
>     >>                in_pred_x,
>     >>                in_succ_x:
>     >>                  begin
>     >>  set_varstate(left,vs_read,[vsf_must_be_valid]);
>     >>                     resultdef:=left.resultdef;
>     >>                     if is_ordinal(resultdef) or
>     is_typeparam(resultdef) then
>     >>                       begin
>     >>                         if (resultdef.typ=enumdef) and
>     >> (tenumdef(resultdef).has_jumps) and
>     >>                            not(m_delphi in
>     current_settings.modeswitches) and
>     >>                            not(nf_internal in flags) then
>     >>  CGMessage(type_e_succ_and_pred_enums_with_assign_not_possible);
>     >>                       end
>     >>
>     >>
>     >> This means that using pred() or succ() intrinsics on enumerated
>     types with
>     >> holes will generate a Compile Time Error.
>     >>
>     >>    To be consistent, I would propose that we also generate
>     >> a Compile Time Error if 'is' or 'as' keyword is used on such a
>     type,
>     >> unless there is a code that really check that the value is not in
>     >> one of the holes ...
>     >>
>     >> Pierre
>     >
>     > That seems fair.  The main problem is what happens if, when
>     allowed,
>     > Prec or Succ are used on such a type on an element that is
>     adjacent to
>     > one of these holes.  Should it skip to the first element at the
>     other
>     > end of the hole or raise an exception? Granted, what happens if
>     you use
>     > Prec or Succ on the first or last element respectively?
>     >
>     > I can theoretically design an algorithm to cover these gaps with
>     Boolean
>     > conditions for the sake of "is", but it's a little bit complex.
>     >
>     > Sorry to bring you in on this particular point, Pierre, but if
>     you call
>     > "Value is TEnum" and Value is of type TEnum but contains an invalid
>     > value (due to being read from an external stream, for example),
>     should
>     > it return True or False?
>
>       My answer would be:
>
>     in FPC modes, simply generate a CompileTimeError as above,
>
>     in Delphi mode, as Delphi states stat the holes are also valid
>     values of the range,
>     then indeed, pred() and succ() can do the simple thing they do
>     when there are no holes,
>     and 'is' or 'as' should then also do the same, i.e. only check
>     that the value is inside
>     the range defined by the lowest and highest values!
>
>       But on course this means that in Delphi mode,
>     even after validating with 'is' you could still have a valid enum
>     value that has no
>     name, i.e. that is in one of those black holes ...
>
>       I don't need to tell you that I do have a preference for the
>     ordinary Free Pascal way!
>
>
> I think Gareth meant his question for enums without holes ;)
>
> Regards,
> Sven
>
>
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20190705/cbcd8639/attachment.html>


More information about the fpc-devel mailing list