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 <pie...@freepascal.org <mailto:pie...@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@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
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to