Recent

Author Topic: [SOLVED]Diferences in Generics in mode FPC or Delphi  (Read 1200 times)

janasoft

  • New Member
  • *
  • Posts: 30
[SOLVED]Diferences in Generics in mode FPC or Delphi
« on: November 27, 2023, 11:28:44 pm »
Hello.
Next code compile and work correctly

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$mode Delphi}
  3.  
  4. program project1;
  5.  
  6. uses generics.collections;
  7.  
  8. type
  9.   TEntity= class
  10.   ID: integer;
  11.   end;
  12.  
  13.   TInheritedEntity = class(TEntity)
  14.   Name: string
  15.   end;
  16.  
  17.   TEntityList = TObjectList <TEntity>;
  18.   TInheritedEntityList = TObjectList <TInheritedEntity>;
  19.  
  20.    TSubject = class
  21.     EntityList: TEntityList;
  22.   end;
  23.  
  24.    TInheritedSubject = class (TSubject)
  25.     EntityList: TInheritedEntityList;
  26.   end;
  27.  
  28.   var subject: TSubject;
  29.       inheritedSubject: TInheritedSubject;
  30.       ent: TEntity;
  31.       inheritedEnt: TInheritedEntity;
  32.  
  33. begin
  34.   ent:= TEntity.Create;
  35.   ent.ID:=0;
  36.   inheritedEnt:= TInheritedEntity.Create;
  37.   inheritedEnt.ID:=1;
  38.   inheritedEnt.Name:='Entity';
  39.  
  40.   subject:= TSubject.create;
  41.   subject.EntityList:=TEntityList.Create;
  42.  
  43.   inheritedSubject:= TInheritedSubject.create;
  44.   inheritedSubject.EntityList:=TInheritedEntityList.Create;
  45.  
  46.   subject.EntityList.Add(ent);
  47.   inheritedSubject.EntityList.Add(inheritedEnt);
  48.  
  49.   writeln(subject.EntityList.Items[0].ClassName);
  50.   writeln(subject.EntityList.Items[0].ID);
  51.   writeln(inheritedSubject.EntityList.Items[0].ClassName);
  52.   writeln(inheritedSubject.EntityList.Items[0].ID);
  53.   writeln(inheritedSubject.EntityList.items[0].Name);
  54.   writeln; write('type enter'); Readln;
  55.  
  56.   subject.EntityList.free;
  57.   subject.Free;
  58.   inheritedSubject.EntityList.Free;
  59.   inheritedSubject.Free;
  60. end.                  

But if i try the same code with FP Generics

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$mode ObjFPC}
  3.  
  4. program project1;
  5.  
  6.  uses  fgl;
  7.  
  8.  type
  9.    TEntity= class
  10.    ID: integer;
  11.    end;
  12.  
  13.    TInheritedEntity = class(TEntity)
  14.    Name: string
  15.    end;
  16.  
  17.    TEntityList = specialize TFPGObjectList <TEntity>;
  18.    TInheritedEntityList = specialize TFPGObjectList <TInheritedEntity>;
  19.  
  20.    TSubject = class
  21.      EntityList: TEntityList;
  22.    end;
  23.  
  24.    TInheritedSubject = class (TSubject)
  25.      EntityList: TInheritedEntityList;
  26.    end;
  27.  
  28.    var subject: TSubject;
  29.        inheritedSubject: TInheritedSubject;
  30.        ent: TEntity;
  31.        inheritedEnt: TInheritedEntity;      

I get the error: Duplicate identifier "EntityList"

I supose that I am doing something wrong or is this the way it has to work?

Regards

Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64
« Last Edit: November 28, 2023, 09:06:07 pm by janasoft »
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

jamie

  • Hero Member
  • *****
  • Posts: 6030
Re: Diferences in Generics in mode FPC or Delphi
« Reply #1 on: November 28, 2023, 12:39:55 am »
maybe put this at the top ?

{$modeSwitch DUPLICATELOCALS}

The only true wisdom is knowing you know nothing

janasoft

  • New Member
  • *
  • Posts: 30
Re: Diferences in Generics in mode FPC or Delphi
« Reply #2 on: November 28, 2023, 09:39:25 am »
Many thanks for your answer jamie but I get the same error
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

bytebites

  • Hero Member
  • *****
  • Posts: 616
Re: Diferences in Generics in mode FPC or Delphi
« Reply #3 on: November 28, 2023, 09:47:42 am »
Change to delphi-mode

cdbc

  • Hero Member
  • *****
  • Posts: 955
    • http://www.cdbc.dk
Re: Diferences in Generics in mode FPC or Delphi
« Reply #4 on: November 28, 2023, 09:50:41 am »
Hi
You've defined:
Code: Pascal  [Select][+][-]
  1.    TSubject = class
  2.     EntityList: TEntityList;
  3.   end;
  4.  
  5.    TInheritedSubject = class (TSubject)
  6.     EntityList: TInheritedEntityList;
  7.   end;
without visibility specifier and by convention they're then "public" / "published" depending on {$M+/-}
That means you WILL have a duplicate identifier. You could put EntityList in "private" then they can't see eachother, but if it's a solution for you, I dunno...
edit: in different units they can't see eachother...
Regards Benny
« Last Edit: November 28, 2023, 09:53:42 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11283
  • FPC developer.
Re: Diferences in Generics in mode FPC or Delphi
« Reply #5 on: November 28, 2023, 10:12:34 am »
I'm usually not a defender of $mode objfpc, but in this case I think it is right, having a class with two different (and differently typed) entitylist fields is a mess.

janasoft

  • New Member
  • *
  • Posts: 30
Re: Diferences in Generics in mode FPC or Delphi
« Reply #6 on: November 28, 2023, 04:25:41 pm »
Hello and first of all, thanks for your answers.
Change to delphi-mode
@bytebites In Delphi mode works correctly. The question is exactly that. Why works correctly in Delphi Mode and fails in FPC mode? What's the difference between both modes?


That means you WILL have a duplicate identifier. You could put EntityList in "private" then they can't see eachother, but if it's a solution for you, I dunno...
edit: in different units they can't see eachother...
Regards Benny

@cdbc I've made this change
Code: Pascal  [Select][+][-]
  1.    TSubject = class
  2.    strict private
  3.      FEntityList: TEntityList;
  4.      procedure SetEntityList(AValue: TEntityList);
  5.    public
  6.      property EntityList:TEntityList read FEntityList write SetEntityList;
  7.    end;
Now  theres is no problem at the moment of declare the variables, but now I get the error 'Incompatible type for arg no. 1: Got "TFPGObjectList<project1.TInheritedEntity>", expected "TFPGObjectList<project1.TEntity>".
So I think it is not an issue of visibility but of type assigning.

@marcov, this is only an exercice about Generics writen in Delphi that I wanted to translate to Lazarus to try to aplicate this technique in order to solve a problem in an aplication. I'm not an expert in lazarus, so I'm sure that there will be better solutions to my problem, but that is not the case. What I really want to know is, like I've told before, why the code in Delphi mode works correctly and fails in FPC mode?

Anyway, thanks again to all for your interest
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11283
  • FPC developer.
Re: Diferences in Generics in mode FPC or Delphi
« Reply #7 on: November 28, 2023, 04:40:27 pm »
What I really want to know is, like I've told before, why the code in Delphi mode works correctly and fails in FPC mode?

Exactly because of what I said. That construct (with one identifier shadowing the other) is considered bad behaviour, and objfpc mode was meant as a cleaned up version of Delphi, so doesn't allow it.

janasoft

  • New Member
  • *
  • Posts: 30
Re: Diferences in Generics in mode FPC or Delphi
« Reply #8 on: November 28, 2023, 09:05:14 pm »
Many thanks @marcov. My doubt is solved.
Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-win64-win32/win64

 

TinyPortal © 2005-2018