Forum > General

Internal error with generics

(1/2) > >>

SymbolicFrank:
I tried to make these classes:


--- 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 ThreadFunction; {$mode Delphi}{$H+} {  Requires PasMP.TPasMPUnboundedQueue in the calling thread!} interface uses  Classes, SysUtils, PasMP, Variants; type   TRunFunction<T> = class;   { TRunResult }   TRunResult = class(TObject)  protected    MyName: string;  public    Value: Variant;    Reference: TObject;    property Name: string read MyName;    constructor Create(ThisName: string);  end;   { TResultQueue }   TResultQueue = class(TPasMPUnboundedQueue<TRunResult>);   { TThreadFunction }   TThreadFunction<T> = function(ThisThread: TRunFunction<T>; ThisPara: T):    TRunResult of object;   { TRunFunction }   TRunFunction<T> = class(TThread)  protected    MyName: string;    MyQueue: TResultQueue;    MyFunction: TThreadFunction<T>;    MyPara: T;    procedure Execute; override;  public    constructor Create(ThisName: string; ThisQueue: TResultQueue;      ThisFunction: TThreadFunction<T>; ThisPara: T);    function PostMessage(ThisValue: Variant; ThisReference: TObject = nil):      Boolean;  end;  implementation { TRunResult } constructor TRunResult.Create(ThisName: string);begin  MyName := ThisName;  Value := Null;  Reference := nil;end; { TRunFunction } procedure TRunFunction<T>.Execute;var  r: TRunResult;begin  if Assigned(MyFunction) then  begin    r := MyFunction(Self, MyPara);    if Assigned(MyQueue) then MyQueue.Enqueue(r);  end;end; constructor TRunFunction<T>.Create(ThisName: string; ThisQueue: TResultQueue;  ThisFunction: TThreadFunction<T>; ThisPara: T);begin  inherited Create(True);   FreeOnTerminate := True;  MyName := ThisName;  MyQueue := ThisQueue;  MyFunction := ThisFunction;  MyPara := ThisPara;   Start;end; function TRunFunction<T>.PostMessage(ThisValue: Variant; ThisReference: TObject  ): Boolean;var  r: TRunResult;begin  if Assigned(MyQueue) then  begin    r := TRunResult.Create(MyName);    r.Value := ThisValue;    r.Reference := ThisReference;    MyQueue.Enqueue(r);  end;end; end.
But it gives an error on that line. What did I do wrong? With fixed parameters it works.

I'm trying to make it more generic by using generics to pass your own kind of parameter(s).

It uses this.

SymbolicFrank:
I inserted the whole unit, it's small.

PascalDragon:

--- Quote from: SymbolicFrank on July 19, 2022, 03:31:00 pm ---But it gives an error on that line. What did I do wrong? With fixed parameters it works.
--- End quote ---

What error on what line? And with what version of FPC and on what platform? When reporting such things, be detailed.


--- 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";}};} ---type  TRunFunction<T> = class;
Forward declarations of generics are not supported in the released versions of FPC. They are only supported from 3.3.1 on. But even then your code triggers a different error for which I have yet to find the cause.

SymbolicFrank:
Ah, my mistake. I overwrote it.

I use trunk on Windows 10 64-bit.

Here:


--- 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";}};} ---  TRunFunction<T> = class(TThread)  protected    MyName: string;                // threadfunction.pas(43,11) Error: Internal error 200204175    MyQueue: TResultQueue;    MyFunction: TThreadFunction<T>;    MyPara: T;    procedure Execute; override;  public    constructor Create(ThisName: string; ThisQueue: TResultQueue;      ThisFunction: TThreadFunction<T>; ThisPara: T);    function PostMessage(ThisValue: Variant; ThisReference: TObject = nil):      Boolean;  end; 
I changed it 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";}};} ---unit ThreadFunction; {$mode Delphi}{$H+} {  Requires PasMP.TPasMPUnboundedQueue in the calling thread!} interface uses  Classes, SysUtils, PasMP, Variants; type   TRunFunction = class;   { TRunResult }   TRunResult = class(TObject)  protected    MyName: string;  public    Value: Variant;    Reference: TObject;    property Name: string read MyName;    constructor Create(ThisName: string);  end;   { TResultQueue }   TResultQueue = class(TPasMPUnboundedQueue<TRunResult>);   { TThreadFunction }   TThreadFunction = function(ThisThread: TRunFunction; Para1, Para2: Variant;    Para3: TObject): TRunResult of object;   { TRunFunction }   TRunFunction = class(TThread)  protected    MyName: string;    MyQueue: TResultQueue;    MyFunction: TThreadFunction;    MyPara1: Variant;    MyPara2: Variant;    MyPara3: TObject;    procedure Execute; override;  public    constructor Create(ThisName: string; ThisQueue: TResultQueue;      ThisFunction: TThreadFunction; Para1, Para2: Variant; Para3: TObject = nil);    function PostMessage(ThisValue: Variant; ThisReference: TObject = nil):      Boolean;  end;  implementation { TRunResult } constructor TRunResult.Create(ThisName: string);begin  MyName := ThisName;  Value := Null;  Reference := nil;end; { TRunFunction } procedure TRunFunction.Execute;var  r: TRunResult;begin  if Assigned(MyFunction) then  begin    r := MyFunction(Self, MyPara1, MyPara2, MyPara3);    if Assigned(MyQueue) then MyQueue.Enqueue(r);  end;end; constructor TRunFunction.Create(ThisName: string; ThisQueue: TResultQueue;  ThisFunction: TThreadFunction; Para1, Para2: Variant; Para3: TObject);begin  inherited Create(True);   FreeOnTerminate := True;  MyName := ThisName;  MyQueue := ThisQueue;  MyFunction := ThisFunction;  MyPara1 := Para1;  MyPara2 := Para2;  MyPara3 := Para3;   Start;end; function TRunFunction.PostMessage(ThisValue: Variant; ThisReference: TObject  ): Boolean;var  r: TRunResult;begin  Result := False;   if Assigned(MyQueue) then  begin    r := TRunResult.Create(MyName);    r.Value := ThisValue;    r.Reference := ThisReference;    MyQueue.Enqueue(r);    Result := True;  end;end; end. 
With two variants and an object as parameters. That works. But I would prefer a generic version.

PascalDragon:

--- Quote from: SymbolicFrank on July 20, 2022, 11:16:11 am ---Ah, my mistake. I overwrote it.

I use trunk on Windows 10 64-bit.
--- End quote ---

Okay, then that is the same error I got in the end. Please report a bug (and preferably with an example that does not require PasMP).

Navigation

[0] Message Index

[#] Next page

Go to full version