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
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to