[fpc-devel] Little feature teaser

Sven Barth pascaldragon at googlemail.com
Sat Aug 3 12:54:13 CEST 2013


On 03.08.2013 12:17, Marco van de Voort wrote:
> In our previous episode, Sven Barth said:
>>> And the same (problem) in C++. Is there some proposal to mitigate the
>>> code duplication? Or the official position is that if the project is
>>> big enough to suffer from the bloat it should avoid itself the
>>> duplicate declarations?
>>
>> The problem is that it's not really possible with the unit concept FPC
>> uses. If you want to share the code with other units the code needs to
>> be callable from the interface section, but when you are working in the
>> implementation section (where most specializations take place) you
>> should not modify the interface section anymore as this needs to trigger
>> a recompilation of all units that depend on that unit.
>
> I thought this is where constraints come in? If the specialization is
> completely defined by the constraint class type, you can already generate
> the specialization and reuse it?

Yes, if constraints are used (most importantly constraints of 
inheritable types) then one could specialize the generic once for the 
given type and be done with it. But there is one problematic case. 
Consider the following:

=== code begin ===

type
   TTest = class
     procedure Test;
   end;

procedure TTest.Test;
begin
   Writeln('Test');
end;

type
   generic TMyGeneric<T: TTest> = class
     class procedure Test;
   end;

class procedure TMyGeneric.Test;
var
   myt: T;
begin
   myt := TTest.Create;
   myt.Test;
   myt.Free;
end;

type
   TTestSub = class
     procedure Test;
   end;

procedure TTestSub.Test;
begin
   Writeln('Foobar');
end;

type
   TMyGenericTTest = specialize TMyGeneric<TTest>;
   TMyGenericTTestSub = specialize TMyGeneric<TTestSub>;
begin
   TMyGenericTTest.Test;
   TMyGenericTTestSub.Test;
end.

=== code end ===

Now currently the output will be the following:

=== output begin ===

Test
Foobar

=== output end ===

If only the base type is specialized the output would be however:

=== output begin ===

Test
Test

=== output end ===

This would of course not only apply to normal methods, but also to non 
virtual constructors. This problem is not trivially to solve...

Maybe one can mark the generic as calling non virtual methods and if the 
class that is used for specialization overrides non-virtual methods then 
it needs to be really respecialized...

Another problem that could come up is overload and/or operator 
selection, because in the first case T will be TTest once and TTestSub 
the other time and in the second time it will be TTest at both times...

So here one would need to record if a called procedure has a overload or 
operator for other types as well and if a type is used for 
specialization that would trigger these overloads than an explicit 
specialization must be done...

I smell a decrease in performance here :P

> But admitted, Delphi doesn't support inline with generics, in that FPC is
> covering new ground.

If I get inlining for generic functions/procedures/methods working as 
well, then we indeed have much new ground compared to Delphi :)

Regards,
Sven



More information about the fpc-devel mailing list