[fpc-pascal] Generic type conflicts
Michael Van Canneyt
michael at freepascal.org
Fri Nov 8 07:32:48 CET 2019
On Thu, 7 Nov 2019, Ben Grasset via fpc-pascal wrote:
> 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;
Thanks for the explanation. All is clear.
As an aside:
In my opinion (keep in mind I am not a big fan of generics) the above code
would be a prime example where one should not be using generics, but simple overloads.
If you need to use GetTypeKind in a generic, I think you're on the wrong path.
Use of IsManagedType() in a generic is stretching it, but GetTypeKind() is over the line.
Michael.
More information about the fpc-pascal
mailing list