Forum > General

Houston we have a problem (with generics in trunk)

(1/2) > >>

Thaddy:
This is probably a case of being blind to the issue, but it may also be a bug.
For some reason, the compiler doesn't allow me to add some generics to a unit, whereas the same generics work as expected when I declare them elsewhere.
The - working! - code is :
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit autofree experimental;{$if fpc_fullversion < 30301}{$error this code needs FPC version 3.3.1 or higher}{$ifend}{$mode delphi}{$interfaces com}{    This code is inspired by the code from ASerge on the Freepascal forum.   I added a interface storage, which makes it possible to drop is and as   At the moment it has the disadvantage that all allocations are governed  by the store so all objects are released when the store is released.  I am working on that....} interface type  { Our own interface type }  IAutoFree = interface(IUnknown)  ['{89D8F215-61FF-4EBF-8C9E-9C027619DC0E}']  end;  { create an instance from a class reference }function Auto(ACls: TClass ): IAutoFree;overload;{ create an instance of a class }function Auto(AObj: TObject): IAutoFree;overload;{ Currently the compiler chokes on this:function Auto<T:class, constructor>:T;overload;procedure Auto<T:class>(out value:T);overload;}function AutoAdd(AObj: TObject): IAutoFree;overload; implementation uses  classes;   type    TAutoFreeHolder = class(TInterfacedObject,IAutoFree)  strict private    FObj: TObject;  protected    function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;winapi;  public    class var Store:IInterfaceList;    class constructor Create;    constructor Create(AObj: TObject);    destructor Destroy; override;  end; { for some reason my current trunk version does not let me   add these two generics to the autofree unit function Auto<T:class, constructor>:T;overload;begin  Result := Auto(T.Create) as T;end; procedure Auto<T:class>(out value:T);overload;begin  Value := Auto(T.Create) as T;end;} function Auto(AObj: TObject): IAutoFree;overload;begin  Result := TAutoFreeHolder.Create(AObj);  TAutoFreeHolder.Store.Add(Result);end; function Auto(ACls: TClass): IAutofree;overload;begin  Result := Auto(ACls.Create);end; function AutoAdd(AObj: TObject): IAutofree;begin  Result := TAutoFreeHolder.Create(AObj);end; class constructor TAutoFreeHolder.Create;begin  Store :=TInterfaceList.Create;end; constructor TAutoFreeHolder.Create(AObj: TObject);begin  inherited Create;  FObj := AObj;end; destructor TAutoFreeHolder.Destroy;begin  FObj.Free;  inherited;end; function TAutoFreeHolder.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;winapi;begin  if Assigned(FObj) and FObj.GetInterface(iid, obj) then    Result := S_OK  else    Result := inherited;end; end.
And a - crude - demo looks like this:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program autoissue;{$mode delphi}{$apptype console}{$ifopt D+}{$assertions on}{$rangechecks on}{$endif}{$modeswitch implicitfunctionspecialization} uses   classes,autofree;{ for some reason my current trunk version does not let me   add these two generics to the autofree unit }function Auto<T:class, constructor>:T;overload;begin  Result := Auto(T.Create) as T;end; procedure Auto<T:class>(out value:T);overload;begin  Value := Auto(T.Create) as T;end; var  a,b,c:TStringlist;  d:TStringStream;begin  writeln('Creates a stringlist  as procedure and is auto free''d');  Auto(a);  a.Add('some');  writeln('content of a is: ',a.text);  writeln('creates a stringlist as a function and is auto free''d');   b:=Auto<TStringlist>;  b.Add('more');  writeln('content of b is: ',b.text);  writeln('add an existing instance to auto free');  c:=TStringlist.create;  autoAdd(c);  writeln('creates an auto free''d class from a paramererized created instance');  d := AutoAdd(TStringStream.Create(a.text+b.text+'This originates as a string stream')) as TStringStream;  writeln(d.datastring);end.
Why can't I add the two generic routines to the core unit?
Am I blind?

(please note this code makes heavy use of features that are ONLY available in trunk, if you do not use trunk, don't reply)

ASerge?, Benny?, PascalDragon?, Others?

avk:
It seems this?

Thaddy:
That may well be related, but does not fully explain why my code works if I define the two generic routines in a different scope. Thanks for thinking with me. Something to research if the issues are related. Gives me something to do  :D

I hate it when my code works, but do not - for the life of me - understand why it works or not.
Now I only know how it works - I designed it - and that it works.
But it is pushing the boundaries of the language, I know.
It is simple code, but deceivingly simple.

Your bug report doesn't mention scope. Will report back to you.

Again, thx for the pointer,

regards,

Thaddy

Thaddy:
@avk,
Sorry I forgot you in the sum up. I should have known better. O:-)

cdbc:
Hi Thaddy
I get the following, when I try to compile your example:
--- Code: Bash  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---[bc@hp auto_intf]$ fpt.sh autoissue.lpr Free Pascal Compiler version 3.3.1-15019-g664f8fc2ba-dirty [2024/01/28] for x86_64Copyright (c) 1993-2024 by Florian Klaempfl and othersTarget OS: Linux for x86-64Compiling autoissue.lprautoissue.lpr(7,11) Warning: Unit "autofree" is experimentalautoissue.lpr(17,25) Error: Can't take the address of constant expressionsautoissue.lpr(17,25) Error: Can't take the address of constant expressionsautoissue.lpr(12,26) Error: Can't take the address of constant expressionsautoissue.lpr(39) Fatal: There were 3 errors compiling module, stoppingFatal: Compilation abortedError: /home/bc/laz_3/fpc/bin/x86_64-linux/ppcx64 returned an error exitcode[bc@hp auto_intf]$The line in question is this:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  Value := Auto(T.Create) as T;Could it be, that my /trunk/ is too old ?!?
Regards Benny

Navigation

[0] Message Index

[#] Next page

Go to full version