Recent

Author Topic: Advanced Records Initialisation bug ?  (Read 3286 times)

Nitorami

  • Sr. Member
  • ****
  • Posts: 491
Re: Advanced Records Initialisation bug ?
« Reply #15 on: October 24, 2022, 09:22:40 pm »
Coming back to this presumed bug - I have not filed a bug report yet because I am uncertain. Up to now I thought that an advanced record would be initialized at runtime on the first access to any of its methods, simply by checking a flag. This would introduce a bit of overhead and speed penalty as the flag would have to be checked on each and every method call, but this may just be the price for the convenience.

But then I found, rather surprisingly, that aGen is initialized properly whenever a local function somewhere within testunit.pas merely mentions one of aGen's methods. The function may never be called, its existence alone is sufficient to prompt the compiler to initialize aGen. Something like this in the unit's implementation part does the job:

Code: Pascal  [Select][+][-]
  1. procedure neverused;
  2. begin
  3.   if false then writeln (aGen.content);
  4. end;

It looks like the compiler does a static analysis at compile time to guess if aGen will be called from somwehere, and if yes, initializes it at program start within fpc_initizalizeunits() ?

Nitorami

  • Sr. Member
  • ****
  • Posts: 491
Re: Advanced Records Initialisation bug ?
« Reply #16 on: March 15, 2023, 06:55:32 pm »
Sorry for re-opening this. While PascalDragon has fixed the initial issue and this has been merged to FPC3.2.3., it only works with TSys as a Class. When making TSys an oldstyle object, the bug is back.

In the code below, LocalGEN is initialised upon program start before Sys has been initialised. That should not be a problem as both are static. Indeed after initalisation of Sys, the address of Sys.LocalGEN is the same as reported during LocalGen's own initalisation. But, Sys.LocalGen.state still returns 0 instead of 55.

Tested with FPC 3.2.3 from 2023/03/05, i386-win32.

Can someone please test and confirm, then I'll file a bug report.

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$IFDEF FPC}
  3.   {$MODE OBJFPC}
  4.   {$MODESWITCH ADVANCEDRECORDS}
  5. {$ENDIF}
  6.  
  7. type  TGen= record
  8.         fstate: longword;
  9.         class operator Initialize (var R: TGen);
  10.         property state: longword read fstate;
  11.       end;
  12.  
  13.       TSys = object //issue is solved for TSys as Class but not as object!
  14.         LocalGen: TGen;
  15.         constructor Init;
  16.       end;
  17.  
  18. (********* TGen *****************************************)
  19. class operator TGen.Initialize (var R: TGen);
  20. begin
  21.   R.fstate := 55;
  22.   writeln ('TGEN initialized ! My address is ',ptruint (@R));
  23. end;
  24.  
  25. (********* TSYS *******************************************)
  26. constructor TSys.Init;
  27. var i: integer;
  28. begin
  29.   inherited;
  30.   writeln ('ok');
  31. //  Initialize (LocalGEN); //this would solve it but then LocalGen.Init is called twice
  32. end;
  33.  
  34. var Sys: TSys;
  35. begin
  36.   writeln ('About initialising Sys');
  37.   Sys.init;
  38.   writeln ('The address of Sys.LocalGEN is ',ptruint (@Sys.LocalGEN));
  39.   writeln ('Accessing Sys.LocalGEN.state results in : ', Sys.LocalGEN.state);
  40.   writeln;
  41. end.
  42.  
  43.  

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Advanced Records Initialisation bug ?
« Reply #17 on: March 15, 2023, 11:17:45 pm »
Can someone please test and confirm, then I'll file a bug report.

Please report.

 

TinyPortal © 2005-2018