Forum > General
Houston we have a problem (with generics in trunk)
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