* * *

Author Topic: Records default no-argument constructor  (Read 1168 times)

SonnyBoyXXl

  • New member
  • *
  • Posts: 40
Records default no-argument constructor
« on: January 13, 2018, 09:40:00 am »
Hello community,

According to the delphi wiki - and I think this is the same for FPC:

Quote
Records are constructed automatically, using a default no-argument constructor, but classes must be explicitly constructed. Because records have a default no-argument constructor, any user-defined record constructor must have one or more parameters.

So two questions:
1) How the default no-argument constructor can be overriden?
2) If not - why? Sometimes its's useful if not all elements are set automatically to zero. A "Init" procedure can be made, but this is one more code instruction and many more cpu instructions. And from an OOP view, this should be possible  8)

thx

SonnyBoy

Thaddy

  • Hero Member
  • *****
  • Posts: 6346
Re: Records default no-argument constructor
« Reply #1 on: January 13, 2018, 09:59:35 am »
1. No, it's not virtual
2. Overriding a default constructor create is also not possible for classes: the default constructor is not virtual. It also does not make sense. https://www.freepascal.org/docs-html/rtl/system/tobject.create.html

Now the fun part: in FPC (trunk) we have management operators that can do what you want: setting things to other values than just zero's and nil's.
http://wiki.freepascal.org/management_operators

I have written several examples in the wiki. Management operators are called automatically.
I 'll show you a slightly modified example of my wiki example that uses the Initialize management operator:
Code: Pascal  [Select]
  1. {$if FPC_FULLVERSION < 30101}{$ERROR this demo needs version 3.1.1 or higher}{$endif}
  2. {$mode delphi}{$macro on}
  3. program TestInitialize;
  4.  
  5. type
  6.     PRec = ^TRec;
  7.     TRec = record
  8.       I : Integer;
  9.       class operator initialize(var aRec:TRec);
  10.     end;
  11.  
  12.     class operator TRec.initialize(var aRec:TRec);
  13.     begin
  14.       //aRec :=Default(TRec); // initialize to default
  15.       FillChar(aRec,SizeOf(aRec),$FF); // initialize to all $FF instead of default.
  16.     end;
  17.  
  18.     procedure printTRec(r : PRec);
  19.     begin
  20.         WriteLn('Initialized TRec field i: ', r^.I = -1);  // should now be $ffffffff (-1) and so print TRUE.
  21.     end;
  22. var
  23.  a,b:PRec;
  24. begin
  25.     New(a);New(b); // standard "new" does not initialize, but now it does!
  26.     PrintTRec(a);
  27.     PrintTRec(b);
  28.     Dispose(a);Dispose(b);
  29. end.

Note you can't do that in Delphi. This feature is specific to FreePascal.
Note for classes you can do something similar by overriding newinstance.

Note that you are also making the wrong assumption that records are always initialized to zero's: That is not the case.... See New()/Dispose() and Default()
« Last Edit: January 13, 2018, 11:12:23 am by Thaddy »
I am enjoining wine, not whine....

SonnyBoyXXl

  • New member
  • *
  • Posts: 40
Re: Records default no-argument constructor
« Reply #2 on: January 13, 2018, 01:22:07 pm »
Hello Thaddy,

that are good news! Thanks!  :D
It's not worse that this is only available in FPC since FPC is my new enviroment ... after abandon using Delphi/TurboPascal for 25 years.

Setting records to zero you are right, my wrong formulation  :)

SonnyBoyXXl

  • New member
  • *
  • Posts: 40
Re: Records default no-argument constructor
« Reply #3 on: January 14, 2018, 11:15:43 am »
Bad news...

I have now the following structurs:

Code: Pascal  [Select]
  1. TD3D12_ROOT_SIGNATURE_DESC = record
  2.         NumParameters: UINT;
  3.         pParameters: PD3D12_ROOT_PARAMETER;
  4.         NumStaticSamplers: UINT;
  5.         pStaticSamplers: PD3D12_STATIC_SAMPLER_DESC;
  6.         Flags: TD3D12_ROOT_SIGNATURE_FLAGS;
  7.         class operator Initialize(var ARecord:TD3D12_ROOT_SIGNATURE_DESC);
  8.     end;
  9.  
  10. TD3D12_ROOT_SIGNATURE_DESC1 = record
  11.         NumParameters: UINT;
  12.         pParameters: PD3D12_ROOT_PARAMETER1;
  13.         NumStaticSamplers: UINT;
  14.         pStaticSamplers: PD3D12_STATIC_SAMPLER_DESC;
  15.         Flags: TD3D12_ROOT_SIGNATURE_FLAGS;
  16.         class operator Initialize(var ARecord:TD3D12_ROOT_SIGNATURE_DESC1);
  17.     end;  
  18.  
  19. TD3D12_VERSIONED_ROOT_SIGNATURE_DESC = record
  20.         Version: TD3D_ROOT_SIGNATURE_VERSION;
  21.         case integer of
  22.             0: (Desc_1_0: TD3D12_ROOT_SIGNATURE_DESC);
  23.             1: (Desc_1_1: TD3D12_ROOT_SIGNATURE_DESC1);
  24.     end;
  25.  
  26.  

Now bringing up this error message for the TD3D12_VERSIONED_ROOT_SIGNATURE_DESC :

DX12.D3D12.pas(2402,53) Error: Data types which require initialization/finalization cannot be used in variant records


The parameter struct is "the same". Different is that pParameters is either a pointer to an array of TD3D12_ROOT_PARAMETER1 or TD3D12_ROOT_PARAMETER, which will be initialized to NIL in the class operator Initialize.

BBasile

  • Sr. Member
  • ****
  • Posts: 400
Re: Records default no-argument constructor
« Reply #4 on: January 14, 2018, 12:55:55 pm »
1. No, it's not virtual
2. Overriding a default constructor create is also not possible for classes: the default constructor is not virtual. It also does not make sense. https://www.freepascal.org/docs-html/rtl/system/tobject.create.html

Now the fun part: in FPC (trunk) we have management operators that can do what you want: setting things to other values than just zero's and nil's.
http://wiki.freepascal.org/management_operators

Oh very nice addition. "AddRef" definitively allows proper handling of value semantic when the actual pseudo value represented by a record contains members that are pointers to heap chunks. The name is probably confusing but i see exactly how to use it since it's like d "__postblit".

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus