I'm currently playing a bit around in the RTTI initialization and finalization code of the FPC, and I found the following:
{ for management operators like initialize call int_initialize }
vmt := PVmt(self);
if assigned(vmt) then
begin
inittable:=vmt^.vInitTable;
if assigned(inittable) then
begin
mopinittable:=RTTIRecordMopInitTable(inittable);
if assigned(mopinittable) then
begin
{$push}
{ ensure that no range check errors pop up with the [0..0] array }
{$R-}
for i:=0 to mopinittable^.Count-1 do
TRTTIRecVarOp(mopinittable^.Entries[i].ManagmentOperator)(PByte(Instance)+mopinittable^.Entries[i].FieldOffset);
{$pop}
end;
end;
end;
Which, first, the very first comment seems to be outdated as it does not call int_initialize/fpc_initialize anymore.
Second, when looking at how records are initialized, it uses a different approach, by simply iterating over the RTTI fields and calling fpc_initialize on them:
{ if possible try to use more optimal initrtti }
with RTTIRecordOp(typeinfo, typeinfo)^ do
begin
recordrtti(data,typeinfo,@int_initialize);
if Assigned(recordop) and Assigned(recordop^.Initialize) then
recordop^.Initialize(data);
end;
Also CleanupInstance is using the "old" rtti way:
{ The RTTI format matches one for records, except the type is tkClass.
Since RecordRTTI does not check the type, calling it yields the desired result. }
if Assigned(Temp) then
RecordRTTI(Self,Temp,@int_finalize);
As this is the only point where RTTIRecordMopInitTable is being used within the whole codebase (at least if the gitlab search is correct), I was wondering what this is about? Is there something special for classes, or is this maybe just a new implementation which is simply not fully finished and therefore just implemented for class initialization?