Recent

Author Topic: problem when using generics and forward class def  (Read 1169 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
problem when using generics and forward class def
« on: March 09, 2023, 03:06:54 pm »
Hello,
see this:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. program Hello;
  4.  
  5. uses
  6.   SysUtils, Classes,
  7.  
  8.   fgl;
  9.  
  10. type
  11.  
  12.   TA = class;
  13.  
  14.   TA = specialize TFPGList<TObject>;
  15.   //TA = class(TObject)
  16.   //end;
  17.  
  18. var
  19.   x: TA;
  20. begin
  21.   x := TA.Create();
  22.   writeln ('Hello World')
  23. end.
  24.  

It gives an error:

Code: Text  [Select][+][-]
  1. Free Pascal Compiler version 3.2.2+dfsg-9ubuntu1 [2022/04/11] for x86_64
  2. Copyright (c) 1993-2021 by Florian Klaempfl and others
  3. Target OS: Linux for x86-64
  4. Compiling main.pas
  5. main.pas(15,8) Error: Duplicate identifier "TA"
  6. main.pas(13,8) Error: Forward type not resolved "TA"
  7. main.pas(25) Fatal: There were 2 errors compiling module, stopping
  8. Fatal: Compilation aborted
  9. Error: /usr/bin/ppcx64 returned an error exitcode
  10.  

I tried this:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. program Hello;
  4.  
  5. uses
  6.   SysUtils, Classes,
  7.  
  8.   fgl;
  9.  
  10. type
  11.  
  12.   TA = class;
  13.  
  14.   //TA = specialize TFPGList<TObject>;
  15.   TA = class(TObject)
  16.   end;
  17.  
  18. var
  19.   x: TA;
  20. begin
  21.   x := TA.Create();
  22.   writeln ('Hello World')
  23. end.
  24.  

Code: Text  [Select][+][-]
  1. Copyright (c) 1993-2021 by Florian Klaempfl and others
  2. Target OS: Linux for x86-64
  3. Compiling main.pas
  4. main.pas(19,3) Note: Local variable "x" is assigned but never used
  5. Linking a.out
  6. 25 lines compiled, 0.4 sec
  7. 1 note(s) issued
  8. Hello World
  9.  
  10.  
  11. ...Program finished with exit code 0
  12. Press ENTER to exit console.
  13.  

What am I doing wrongo?
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: problem when using generics and forward class def
« Reply #1 on: March 09, 2023, 03:31:50 pm »
https://www.freepascal.org/docs-html/current/ref/refse54.html#x108-1320008.3

Remark It is not possible to make a forward definition of a class which is a specialization of a generic, i.e. the following will not compile:

Code: Pascal  [Select][+][-]
  1.   TMyClass = Class;  
  2.  
  3.   // Other declarations  
  4.  
  5.   TMyClass = specialize TList<T>;
  6.  

 %)
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: problem when using generics and forward class def
« Reply #2 on: March 09, 2023, 03:39:12 pm »
When specializing generic classes you should inherit from them:
Code: Pascal  [Select][+][-]
  1.   TTest = class;
  2.   TTest = cass(specialize TFPGList<TObject>); // Works
This way the compiler knows that the resulting type is indeed an instance of a class.

There are some other cases where direct specialization can lead to some problems. For example partial specialization:
Code: Pascal  [Select][+][-]
  1.   generic TTest<T, U> = class(TObject);
  2.   generic TTestInt<U> = class(specialize TTest<Integer, U>); // Works
  3.   generic TTestInt<U> = specialize TTest<Integer, U>;  // Doesn't
This is why you typically see the syntax "class(specialize ...);", it avoids some of the limitations FPC has for generics

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: problem when using generics and forward class def
« Reply #3 on: March 09, 2023, 03:41:26 pm »
When specializing generic classes you should inherit from them:
Code: Pascal  [Select][+][-]
  1.   TTest = class;
  2.   TTest = cass(specialize TFPGList<TObject>); // Works
This way the compiler knows that the resulting type is indeed of type class.

There are some other cases where direct specialization can lead to some problems. For example partial specialization:
Code: Pascal  [Select][+][-]
  1.   generic TTest<T, U> = class(TObject);
  2.   generic TTestInt<U> = class(specialize TTest<Integer, U>); // Works
  3.   generic TTestInt<U> = specialize TTest<Integer, U>;  // Doesn't
This is why you typically see the syntax "class(specialize ...);", it avoids some of the limitations FPC has for generics

Thanks

Code: Pascal  [Select][+][-]
  1. TTest = cass(specialize TFPGList<TObject>); // Works
  2.  

will save me from declaring a TObject and cast everywhere.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: problem when using generics and forward class def
« Reply #4 on: March 09, 2023, 03:51:22 pm »
Forward generic class declarations are a feature in trunk, not 3.2.0. nor 3.2.2.
https://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_forward_declarations_of_generic_types
« Last Edit: March 09, 2023, 03:59:14 pm by Thaddy »
Specialize a type, not a var.

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: problem when using generics and forward class def
« Reply #5 on: March 09, 2023, 04:05:14 pm »
Forward generic class declarations are a feature in trunk, not 3.2.0. nor 3.2.2.
https://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_forward_declarations_of_generic_types

When the guys release the trunk,
We all make party and get drunk.

  :P
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: problem when using generics and forward class def
« Reply #6 on: March 09, 2023, 05:03:14 pm »
Forward generic class declarations are a feature in trunk, not 3.2.0. nor 3.2.2.
https://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_forward_declarations_of_generic_types

For sure I am stupid to ask, but how does this relate to my original question?

In the link posted there's a reference to "Support for forward declarations of generic types", i.e. a generic initially forward declared and later declared,
while my example is a simple type forward declaration that is later declared as a specialization of a generic.

Are the two things the same?

(this apart, I could have been smarter and search the doc before posting this thread)
« Last Edit: March 10, 2023, 11:22:36 am by tt »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: problem when using generics and forward class def
« Reply #7 on: March 09, 2023, 10:55:06 pm »
Are the two things the same?

No, they're not. You can not forward declare specializations.

 

TinyPortal © 2005-2018