[fpc-devel] Dangerous optimization in CASE..OF

Florian Klämpfl florian at freepascal.org
Sun Jul 2 19:39:30 CEST 2017


Am 02.07.2017 um 19:29 schrieb Martok:
> Addendum to this:
> 
>> This was also always my intuition that the else block is also triggered for
>> invalid enum values (the docs even literally say that, "If none of the case
>> constants match the expression value") - and it *is* true in Delphi.
> There is a reason why this is true in Delphi: because this is the way it has
> been documented in Borland products for at least 25 years!
> 
> I have checked with the TP7 language reference (it pays to keep books around),
> which defines the following things:
>  - Enumeration element names are implicitly defined as typed constants of their
> enum type
>  - The enum type is either Byte (<=256 elements) or Word.
>  - Subrange types are defined as the smallest type that can contain their range
>  - Case statements execute the statements of the matching case label, or the
> else block otherwise
> 
> Note that they actually defined enumerations as what I called 'fancy constants'
> before.
> 
> 
> The Delphi 4 language reference (also in book form, which is a bit more detailed
> than what is in the .hlp files) uses more precise language:
>  - Enumeration element names are implicitly defined as typed constants of their
> enum type
>  - The enum type is either Byte, Word, or Longword, depending on $Z and element
> count
>  - Subrange types are defined as the smallest type that can contain their range
>  - it is legal to inc/dec outside of a subrange, example from the book:
>    type Percentile = 1..99;
>    var I: Percentile;
>    begin
>      I:= 99;
>      inc(I);   // I is now 100
>    So if this is a legal statement, subrange types can contain values outside of
> their range. The description in the German version is "Die Variable wird in
> ihren Basistyp umgewandelt", the variable becomes its base type.
>  - Case statements execute *precisely one* of their branches: the statements of
> the matching case label, or the else block otherwise
> 
> So, in D4, we have enums as fancy constants, subrange-types are not safe (so
> enums can also never be), and case statements cannot fail.
> 
> 
> FPC's language reference has no formal definition of what enums or subranges
> really are, and the same language as TP7 regarding case statements.
> 
> 
> So at least in modes TP and DELPHI, the optimisation in question is formally wrong.

So this means:

var
  b : boolean;

begin
  b:=boolean(3);
  if b then
    writeln(true)
  else if not(b) then
    writeln(false)
  else
    writeln(ord(b));
end.

writes 3 in delphi?




More information about the fpc-devel mailing list