Forum > FPC development

Records default no-argument constructor

(1/2) > >>

SonnyBoyXXl:
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.
--- End quote ---

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:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$if FPC_FULLVERSION < 30101}{$ERROR this demo needs version 3.1.1 or higher}{$endif}{$mode delphi}{$macro on}program TestInitialize; type    PRec = ^TRec;    TRec = record      I : Integer;      class operator initialize(var aRec:TRec);    end;     class operator TRec.initialize(var aRec:TRec);    begin      //aRec :=Default(TRec); // initialize to default      FillChar(aRec,SizeOf(aRec),$FF); // initialize to all $FF instead of default.    end;     procedure printTRec(r : PRec);    begin        WriteLn('Initialized TRec field i: ', r^.I = -1);  // should now be $ffffffff (-1) and so print TRUE.    end; var a,b:PRec; begin    New(a);New(b); // standard "new" does not initialize, but now it does!     PrintTRec(a);    PrintTRec(b);    Dispose(a);Dispose(b);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()

SonnyBoyXXl:
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:
Bad news...

I have now the following structurs:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TD3D12_ROOT_SIGNATURE_DESC = record        NumParameters: UINT;        pParameters: PD3D12_ROOT_PARAMETER;        NumStaticSamplers: UINT;        pStaticSamplers: PD3D12_STATIC_SAMPLER_DESC;        Flags: TD3D12_ROOT_SIGNATURE_FLAGS;        class operator Initialize(var ARecord:TD3D12_ROOT_SIGNATURE_DESC);    end;  TD3D12_ROOT_SIGNATURE_DESC1 = record        NumParameters: UINT;        pParameters: PD3D12_ROOT_PARAMETER1;        NumStaticSamplers: UINT;        pStaticSamplers: PD3D12_STATIC_SAMPLER_DESC;        Flags: TD3D12_ROOT_SIGNATURE_FLAGS;        class operator Initialize(var ARecord:TD3D12_ROOT_SIGNATURE_DESC1);    end;   TD3D12_VERSIONED_ROOT_SIGNATURE_DESC = record        Version: TD3D_ROOT_SIGNATURE_VERSION;        case integer of            0: (Desc_1_0: TD3D12_ROOT_SIGNATURE_DESC);            1: (Desc_1_1: TD3D12_ROOT_SIGNATURE_DESC1);    end;  
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.

guest58172:

--- Quote from: Thaddy 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

--- End quote ---

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".

Navigation

[0] Message Index

[#] Next page

Go to full version