[fpc-pascal] Generics: constructor restriction fail

silvioprog silvioprog at gmail.com
Tue Nov 11 21:53:05 CET 2014


On Sat, Nov 1, 2014 at 9:04 AM, Sven Barth <pascaldragon at googlemail.com>
wrote:

> On 31.10.2014 00:04, silvioprog wrote:
>
>> Hello,
>>
>> Following this article:
>>
>> http://alex.ciobanu.org/?p=51
>>
>> The compiler does not check the constructor restriction.
>>
>> Try this test:
>>
>> {$mode delphi}
>>
>>    TTest = class
>>    private // hidding the constructor to cause a compiler error
>>      constructor Create;
>>    end;
>>
>>    TGen<T: class, constructor> = class
>>    end;
>>
>> constructor TTest.Create;
>> begin
>> end;
>>
>> var  Gen: TGen<TTest>;
>> begin
>>    Gen := TGen<TTest>.Create;
>> end;
>>
>> It compiles well in FPC (from trunk), but the same code in XE is:
>>
>> "[dcc32 Error] Unit1.pas(36): E2513 Type parameter 'T' must have one
>> public parameterless constructor named Create"
>>
>> It is a bug in FPC or I need to enable some directive switch?
>>
>
> "constructor" restrictions are not enforced currently, because with the
> way FPC handles generics compared to Delphi they are a bit useless.
> Consider this:
>
> === code begin ===
>
> type
>   TTest = class
>   strict private // just to keep it hidden in the same unit
>     constructor Create;
>   end;
>
> var
>   t: TTest;
> begin
>   t := TTest.Create;
> end.
>
> === code end ===
>
> The above code snippet will compile, because the compiler will use the
> next best constructor that it can find which is at least the constructor of
> TObject.
>
> Next snippet:
>
> === code begin ===
>
> type
>   TGeneric<T> = class
>     procedure Test;
>   end;
>
> procedure TGeneric<T>.Test;
> begin
>   Writeln(T.Bar);
> end;
>
> begin
> end.
>
> === code end ===
>
> This will correctly compile in FPC, but not in Delphi, because FPC handles
> quite some type checking at specialization time not at declaration time. So
> this will fail to specialize (at compile time) if T does not implement a
> class method called "Bar".
>
> Now let's put these two concepts together and exchange "T.Bar" with
> "T.Create" (and change the "Writeln" to something else of course ;) ) and
> it will still compile as long as T provides a Create method. Now as long T
> is a class this will always be the case, because there is at least the
> TObject constructor.
>

Indded. Thanks for the explanation brother. =)


> That's why the "constructor" constraint is currently not handled in
> anyway. That said there'd still be a usecase for this to ensure that there
> is a default constructor in the class. Also it might be worthwhile to
> rethink the type checking in case of mode Delphi for generics... :/
>

It seems good to check it like Delphi em mode delphi, keeping the
compatibility. =/

-- 
Silvio Clécio
My public projects - github.com/silvioprog
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20141111/0ebb8925/attachment.html>


More information about the fpc-pascal mailing list