Recent

Author Topic: Generic class and visibilty of private members  (Read 1404 times)

Bart

  • Hero Member
  • *****
  • Posts: 5274
    • Bart en Mariska's Webstek
Generic class and visibilty of private members
« on: January 15, 2021, 09:56:09 pm »
Hi,

If I derive a specialized class from a generic class (which is defined in a separate unit), then in that class (and instances of that class) I have access to private fields of that class.
Is that to be expected?
For "normal" classes this is not the case.

Given the following unit:
Code: Pascal  [Select][+][-]
  1. unit foo;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10. type
  11.  
  12.   { TFoo }
  13.  
  14.   TFoo = class
  15.   private
  16.     PrivateVar: String;
  17.   end;
  18.  
  19.  
  20.   type
  21.     generic TBar<T>=class
  22.     private
  23.       PrivateVar:T;
  24.   end;
  25.  
  26.   TBarInt = specialize TBar<Integer>;
  27.  
  28. implementation
  29.  
  30. end.

And then this program:
Code: Pascal  [Select][+][-]
  1. program vis;
  2.  
  3. {$mode objfpc}
  4. {$h+}
  5.  
  6. uses foo;
  7.  
  8. type
  9.   TBarChar = class (specialize TBar<Char>);
  10.   TFooChild = class(TFoo);
  11.  
  12. var
  13.   AFoo: TFoo;
  14.   AFooChild: TFooChild;
  15.   ABarChar: TBarChar;
  16.   ABarInt: TBarInt;
  17.  
  18.  
  19. begin
  20.   ABarChar.PrivateVar := 'A';  //compiles (to my surprise: why?)
  21.   ABarInt.PrivateVar := 1;     //vis.lpr(21,11) Error: identifier idents no member "PrivateVar" (if the above is allowed, why not this?)
  22.   AFooChild.PrivateVar := '';  //vis.lpr(22,13) Error: identifier idents no member "PrivateVar" (as expected)
  23.   AFoo.PrivateVar := '';       //vis.lpr(23,8) Error: identifier idents no member "PrivateVar"  (as expected)
  24. end.

Never mind that the code is bogus and would crash instantly  O:-)

Bart

GAN

  • Sr. Member
  • ****
  • Posts: 370
Re: Generic class and visibilty of private members
« Reply #1 on: January 15, 2021, 10:28:09 pm »
I'm not an expert on the subject, but I found this:

Quote
A private member is invisible outside of the unit or program where its class is
declared. In other words, a private method cannot be called from another module,
and a private field or property cannot be read or written to from another module.

Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3 - LazReport

Bart

  • Hero Member
  • *****
  • Posts: 5274
    • Bart en Mariska's Webstek
Re: Generic class and visibilty of private members
« Reply #2 on: January 15, 2021, 10:48:00 pm »
But then why the discrepancy betweenABarChar (child of TBar, declared in main program) and TFooChils (child of TFoo, declared in main program)?

Bart

speter

  • Sr. Member
  • ****
  • Posts: 345
Re: Generic class and visibilty of private members
« Reply #3 on: January 16, 2021, 01:50:30 am »
I believe that "specialize" = create.

if you add:
Code: Pascal  [Select][+][-]
  1.   tanotherfoo = class(Tfoo)
  2.   private
  3.     voo : integer;
  4.   end;
to your program; you can then have:
Code: Pascal  [Select][+][-]
  1. var
  2.   afoo2 : tanotherfoo;
  3. ...
  4.   afoo2.voo:=6;

So, it's apples and oranges (all fruit). :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: Generic class and visibilty of private members
« Reply #4 on: January 16, 2021, 02:26:18 am »
I don't know why all use foo and bar. I can't visualize that and I never understood these examples...

I prefer TCar. TPerson.  8)

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Generic class and visibilty of private members
« Reply #5 on: January 16, 2021, 02:31:21 am »
I don't know why all use foo and bar. I can't visualize that and I never understood these examples...

I prefer TCar. TPerson.  8)

I like TMaserati  My self  :)
The only true wisdom is knowing you know nothing

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Generic class and visibilty of private members
« Reply #6 on: January 16, 2021, 02:47:51 am »
@lainz

Perhaps you can't visualize that .
But you can realize that:

Let's go to the bar and drink some foo .....

Winni

speter

  • Sr. Member
  • ****
  • Posts: 345
Re: Generic class and visibilty of private members
« Reply #7 on: January 16, 2021, 02:50:25 am »
[removed off colour humour] ;-)
« Last Edit: January 16, 2021, 11:50:11 am by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Generic class and visibilty of private members
« Reply #8 on: January 16, 2021, 03:30:22 am »
Generic class is just a template and TBarChar is derived from TBar which is specialized (i.e. declared) in the same unit (vis), therefore you have access to private fields. It's not a bug IMO.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Generic class and visibilty of private members
« Reply #9 on: January 16, 2021, 11:50:44 am »
If I derive a specialized class from a generic class (which is defined in a separate unit), then in that class (and instances of that class) I have access to private fields of that class.

Regarding terminology: you do not “derive” a specialized class from a generic one, you “specialize” a generic class. And your TBarChar and TBarFoo “derive” from a specialized class (which for all intents and purposes is just a normal class now).

Never mind that the code is bogus and would crash instantly  O:-)

It should not work. It currently works, because the compiler is essentially recreating the class inside your main program file thus it's essentially an access from the same unit. As the compiler could in theory however reuse the specialization from another unit the code would then fail. Delphi behaves correctly here. Please report as a bug.

Bart

  • Hero Member
  • *****
  • Posts: 5274
    • Bart en Mariska's Webstek
Re: Generic class and visibilty of private members
« Reply #10 on: January 16, 2021, 05:42:53 pm »
It should not work.
...
Please report as a bug.

Reported as issue #38363.

Bart

 

TinyPortal © 2005-2018