[fpc-pascal] Generic type conflicts

Ben Grasset operator97 at gmail.com
Thu Nov 7 18:28:51 CET 2019


On Thu, Nov 7, 2019 at 10:23 AM Michael Van Canneyt <michael at freepascal.org>
wrote:

> If I understood Sven's example correct, then the compiler does exactly this
> already.
>

It does in the sense of *code generation* for things that are specifically
compiler intrinsics (which I was aware of), but not in a sense that makes
the issue Ryan was posting about here avoidable. Maybe this will explain
what I'm trying to get at a bit better:

program Example;

{$mode ObjFPC}

// Without actually specializing and using GDiv,
// this program compiles fine.

generic function GDiv<T>(const A, B: T): T; inline;
begin
  if GetTypeKind(T) in [tkInteger, tkInt64, tkQWord] then
    Result := A div B
  else if GetTypeKind(T) = tkFloat then
    Result := A / B
  else
    Result := Default(T);
end;

// However, once we do specialize it...

procedure UseGDiv;
begin
  // Example.pas(13,17) Error: Incompatible types: got "Double" expected
"Int64"
  WriteLn(specialize GDiv<Int64>(1, 2));
  // Example.pas(11,17) Error: Operator is not overloaded: "Double" div
"Double"
  WriteLn(specialize GDiv<Double>(1, 2));
end;

// Note: I'm fully aware that having the *normal* if-statement work in such
a way that the
// the above would compile is neither feasible or a good idea. However,
imagine something
// like the following hypothetical version of GDiv, which would rely on the
conditional
// compilation aspect of the scanner to be aware of more than it currently
is, and also
// for the conditional compilation syntax to be somewhat more advanced:

generic function GDiv<T>(const A, B: T): T; inline;
begin
  // Here, we're doing precisely the same kind of thing that is currently
  // possible with SizeOf, Declared, Defined, and so on.
  {$IF GetTypeKind(T) in [tkInteger, tkInt64, tkQWord]}
    Result := A div B
  {$ELSEIF GetTypeKind(T) = tkFloat}
    Result := A / B
  {$ELSE}
    Result := Default(T);
  {$ENDIF}
end;

begin
end.

Of course, implementing that kind of thing in the scanner would likely be
far more difficult than implementing it as something that happens in
"normal" code, via some syntax or perhaps intrinsic that makes it
distinctively a fully-statically-considered conditional, as opposed to a
partially-statically considered one as is the case with normal "if".
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20191107/2b941af3/attachment.html>


More information about the fpc-pascal mailing list