[fpc-pascal] Generic type conflicts

Sven Barth pascaldragon at googlemail.com
Wed Nov 6 08:01:28 CET 2019


Ben Grasset via fpc-pascal <fpc-pascal at lists.freepascal.org> schrieb am
Mi., 6. Nov. 2019, 04:49:

> On Tue, Nov 5, 2019 at 5:24 PM Sven Barth via fpc-pascal <
> fpc-pascal at lists.freepascal.org> wrote:
>
>> Does this really work? Cause the compiler should nevertheless typecheck
>> the code in the other branch and thus without casts that shouldn't compile.
>> Also if it should indeed work, it would also work without the
>> if-expression, but with an if-statement.
>>
>
> Hm, it actually doesn't quite for that particular example, testing it for
> real. It definitely did for a few other generic things I experimented with
> though (that were impossible otherwise.) I'll see if I can find the source
> files anywhere.
>
> Why would it work the same way as a normal if statement, though? Isn't the
> non-evaluation of the false branch pretty much the only point of the
> ternary "form"? E.G. you'd specifically use it when you had two branches
> that you knew would never *both* be compilable.
> You'd be able to do the same thing with an {$IFDEF}, for example, if
> {$IFDEFS} specifically carried through across generic specializations.
>

A normal if-statements has the same non-evaluation. However that it might
not be evaluated does not mean that it is not type checked. Especially as
the type of the expression is taken from the if-branch. Imagine this:

=== code begin ===

SomeLongint := if SomethingFalse then SomeOtherLongint else SomeString;

=== code end ===

The if-branch is obviously not taken here. But nevertheless the type of the
whole condition is LongInt, because the type of the if-branch is LongInt.
Thus there will be a type error in the else-branch even before the compiler
determines that the if-condition is constant and False.

And the if-expression behaves like an if-clause, because the compiler
transforms it as such. The above example becomes (in the node tree)
essentially the following (general case without further optimizations):

=== code begin ===

if SomethingFalse then
  tmpLongInt := SomeOtherLongint
else
  tmpLongInt := SomeString;
SomeLongint := tmpLongInt;

===code end ===

Regards,
Sven

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20191106/65e916d4/attachment-0001.html>


More information about the fpc-pascal mailing list