Recent

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

Nitorami

  • Sr. Member
  • ****
  • Posts: 426
Advanced Records Initialisation bug ?
« on: August 13, 2022, 10:15:53 am »
Advanced Records allow to define Class operators initialise/finalise to autoinitialise/clean up the record. That is very handy and spares extra calls to Create and Free as for Classes.

I used this for a random generator; the generator is a record and its state is autoinitialised. Works brillant when the record is global, also works when it is a Class field, BUT fails within a Class hierarchy. See below.
The generator rgen is a field of TSys0, and is correctly initilalised when creating an instance of TSys0, but NOT when creating an instance of TSys. Although TSys.Create calls TSys0.Create, rgen is not initialised.... have I misunderstood something ?

Attached the source files for testing. Sorry no Lazarus project, I am still used to work with the Textmode IDE. And I know the generator is crap, this is just for testing.
FPC3.2.2, win32, mode objfpc

Code: Pascal  [Select][+][-]
  1. uses randgen2;
  2.  
  3. type TSys0 = Class
  4.        rgen: TRandgen;
  5.        constructor create;
  6.        destructor destroy; override;
  7.      end;
  8.  
  9. constructor TSys0.Create;
  10. begin
  11.   writeln ('TSys0 now being created');
  12.   Inherited create;
  13.   writeln ('Print random numbers');
  14.   writeln (rgen.random32);
  15.   writeln (rgen.random32);
  16.   writeln (rgen.random32);
  17.   writeln (rgen.random32);
  18. end;
  19.  
  20. destructor TSys0.destroy;
  21. begin
  22.   inherited destroy;
  23. end;
  24.  
  25. //############################
  26.  
  27. type TSys = Class (TSys0)
  28.        constructor create;
  29.        destructor destroy; override;
  30.      end;
  31.  
  32. constructor TSys.Create;
  33. begin
  34.   Inherited create;
  35. end;
  36.  
  37. destructor TSys.destroy;
  38. begin
  39.   inherited destroy;
  40. end;
  41.  
  42. //############################
  43.  
  44. var C: TSys0;
  45.  
  46. begin
  47.   writeln;
  48.   writeln ('Create instance of TSys0...');
  49.   C := TSys0.Create;
  50.   C.Free;
  51.  
  52.   writeln;
  53.   writeln ('Create instance of TSys...');
  54.   C := TSys.Create;
  55.   C.Free;
  56. end.
  57.  

BrunoK

  • Sr. Member
  • ****
  • Posts: 343
  • Retired programmer
Re: Advanced Records Initialisation bug ?
« Reply #1 on: August 13, 2022, 02:53:11 pm »
Code: Pascal  [Select][+][-]
  1. type TSys = Class (TSys0)
  2.        // rgenB: TRandgen; // <-- comment / uncomment changes rgen initialize ~bk
  3.        constructor create;
  4.        destructor destroy; override;
  5.      end;
Modifying TSys fields gives strange result that depend on commenting/un-commenting rgenB.  Strange or did I make a mistake ?

ASerge

  • Hero Member
  • *****
  • Posts: 1975
Re: Advanced Records Initialisation bug ?
« Reply #2 on: August 14, 2022, 12:42:49 am »
Sorry no Lazarus project, I am still used to work with the Textmode IDE. And I know the generator is crap, this is just for testing.
FPC3.2.2, win32, mode objfpc
Bug reproduced. А simplified version that is also suitable for Delphi:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$IFDEF FPC}
  3.   {$MODE OBJFPC}
  4.   {$MODESWITCH ADVANCEDRECORDS}
  5. {$ENDIF}
  6.  
  7. type
  8.   TState = record
  9.   strict private
  10.     FState: LongWord;
  11.     class operator Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Instance: TState);
  12.   public
  13.     property State: LongWord read FState;
  14.   end;
  15.  
  16. class operator TState.Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Instance: TState);
  17. begin
  18.   Writeln('TState now being initialised');
  19.   Instance.FState := 1;
  20. end;
  21.  
  22. type
  23.   TSys0 = class(TObject)
  24.     FItem: TState;
  25.     constructor Create;
  26.   end;
  27.  
  28.   TSys = class(TSys0)
  29.     //FItem2: TState;
  30.   end;
  31.  
  32. constructor TSys0.Create;
  33. begin
  34.   inherited;
  35.   Writeln(ClassName + ' now being created');
  36.   Writeln('State=', FItem.State);
  37. end;
  38.  
  39. var
  40.   C: TSys;
  41. begin
  42.   Writeln('Create instance of TSys...');
  43.   C := TSys.Create;
  44.   C.Free;
  45.   Readln;
  46. end.
In FPC:
Quote
Create instance of TSys...
TSys now being created
State=0
In Delphi:
Quote
Create instance of TSys...
TState now being initialised
TSys now being created
State=1

PascalDragon

  • Hero Member
  • *****
  • Posts: 4523
  • Compiler Developer
Re: Advanced Records Initialisation bug ?
« Reply #3 on: August 14, 2022, 03:44:56 pm »
Fixed in 27c1bb3b. If no issues occur this will likely be merged to 3.2.3 as well.

 

TinyPortal © 2005-2018