Recent

Author Topic: Declaring Generic class in FPC does not function like normal class declaration  (Read 1980 times)

Schmitty2005

  • Jr. Member
  • **
  • Posts: 65
When declaring a generic class, you have to inherit Tobject, or there is an error from FPC.  Where as declaring a non generic class, Tobject is already inherited from automatically.  You can delcare them as just a
Code: Pascal  [Select][+][-]
  1. class
  or as a
Code: Pascal  [Select][+][-]
  1. class(Tobject)
and they work just fine.

This took me a few minutes to figure out.  Is it expected to have to explicitly inherit Tobject for a generic class?

Code: Pascal  [Select][+][-]
  1. {$MODE DELPHI}
  2. program generic;
  3.  
  4. uses classes;
  5.  
  6. Type
  7.   //TstandardClass = class (Tobject)   //compiles and works
  8.   TstandardClass = class           //compiles and works also
  9.   private
  10.     fField1 : Integer;
  11.   public
  12.     property fieldStandard : Integer read fField1 write fField1;
  13.     procedure showfield;
  14.   end;
  15.  
  16.   TGenericTest<T> = class (Tobject) //compiles and works
  17.   //TGenericTest<T> = class ()      //Causes error Message (see below )
  18.     private
  19.       fField : T;
  20.     public
  21.       property FieldGeneric : T read fField write fField;
  22.       procedure showField ;
  23.     end;
  24.  
  25.     procedure TGenericTest<T>.showField;
  26.     begin
  27.       writeln(fField);
  28.     end;
  29.  
  30.     procedure TStandardClass.showField;
  31.     begin
  32.       writeln(fField1);
  33.     end;
  34. var
  35.   testing : TGenericTest<Integer>;
  36.   otherTest : TstandardClass;
  37. begin
  38.   otherTest := TStandardClass.Create;
  39.   otherTest.FieldStandard := 77;
  40.   otherTest.showField;
  41.   testing := TGenericTest<Integer>.create();
  42.   testing.FieldGeneric := 33;
  43.   testing.showField;
  44.   otherTest.free;
  45.   testing.free;
  46. end.
  47. {
  48. Free Pascal Compiler version 3.2.2+dfsg-32 [2024/01/05] for x86_64
  49. Copyright (c) 1993-2021 by Florian Klaempfl and others
  50. Target OS: Linux for x86-64
  51. Compiling generic.pas
  52. generic.pas(9,28) Error: Type identifier expected
  53. generic.pas(9,28) Error: class type expected, but got "<erroneous type>"
  54. generic.pas(9,28) Error: Type identifier expected
  55. generic.pas(9,28) Error: class type expected, but got "<erroneous type>"
  56. generic.pas(31) Fatal: There were 4 errors compiling module, stopping
  57. Fatal: Compilation aborted
  58. Error: /usr/bin/ppcx64 returned an error exitcode
  59. }
  60.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
In your example you have empty "()" brackets in case of the commented generic.

You don't put those for the normal class. Just leave them away for the generic too, and you should not need TObject.

Thaddy

  • Hero Member
  • *****
  • Posts: 19169
  • Glad to be alive.
If you use class it is automatically derived from TObject.
Declaring TMyClas = class is the same as TMyClass = class (Tobject). The EXACT same.
objects are fine constructs. You can even initialize them with constructors.

Schmitty2005

  • Jr. Member
  • **
  • Posts: 65
In your example you have empty "()" brackets in case of the commented generic.

You don't put those for the normal class. Just leave them away for the generic too, and you should not need TObject.

Thank you.  I did not notice! 

So I guess that inherits nil , causing it to fail, instead of Tobject , which would work.

Schmitty2005

  • Jr. Member
  • **
  • Posts: 65
If you use class it is automatically derived from TObject.
Declaring TMyClas = class is the same as TMyClass = class (Tobject). The EXACT same.

Thank you.  I did not realize the difference from class () and class inheritance.  I assumed the compiler would see them the same and create class(Tobject) regardless.   My program was failing like it should.

Schmitty2005

  • Jr. Member
  • **
  • Posts: 65
When using Delphi CE,
Code: Pascal  [Select][+][-]
  1. TMyClass = class ()
with throw an error in the IDE of E0209 " 'Expected Identifier before ')' " before compilation. (E0209 may not be the exact error number, but something similar)

Lazarus does not catch this until compilation.   FPC compiler gives a rather cryptic error.

It is an easy fix, but it would have been nice if the IDE gave a warning. Should this be a suggestion for Lazarus IDE ?

« Last Edit: August 09, 2025, 11:37:49 pm by Schmitty2005 »

Thaddy

  • Hero Member
  • *****
  • Posts: 19169
  • Glad to be alive.
Your code works in trunk. No time to investigate that further, because 3.2.2 stays. Maybe it is fixed in the upcoming 3.2.4?
Try the RC.
« Last Edit: August 10, 2025, 06:37:11 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6395
  • Compiler Developer
So I guess that inherits nil , causing it to fail, instead of Tobject , which would work.

No, that does not inherit Nil, that is simply not valid syntax.

Schmitty2005

  • Jr. Member
  • **
  • Posts: 65
Your code works in trunk. No time to investigate that further, because 3.2.2 stays. Maybe it is fixed in the upcoming 3.2.4?
Try the RC.

Thank you for checking.  Not fixed in 3.2.3rc1.  I also just tried in trunk 3.3.1 with last commit from about  a week ago and it does not work.  Did this get fixed in the last few days ?

Note that the error causing line is commented out in my source above  :
Code: Pascal  [Select][+][-]
  1. TGenericTest<T> = class (Tobject) //compiles and works
  2.   //TGenericTest<T> = class ()      //Causes error Message (see below )
  so a quick copy, paste, and run will compile.



PascalDragon

  • Hero Member
  • *****
  • Posts: 6395
  • Compiler Developer
Your code works in trunk. No time to investigate that further, because 3.2.2 stays. Maybe it is fixed in the upcoming 3.2.4?
Try the RC.

Thank you for checking.  Not fixed in 3.2.3rc1.  I also just tried in trunk 3.3.1 with last commit from about  a week ago and it does not work.  Did this get fixed in the last few days ?

Note that the error causing line is commented out in my source above  :
Code: Pascal  [Select][+][-]
  1. TGenericTest<T> = class (Tobject) //compiles and works
  2.   //TGenericTest<T> = class ()      //Causes error Message (see below )
  so a quick copy, paste, and run will compile.

class() is simply not correct syntax. Leave away the parenthesis or use class(TObject).

 

TinyPortal © 2005-2018