Can I rely on the fact, that an interface field in a record is always initialized to nil?
TMyRec = record
FGuard : IInterface;
FObject : TObject;
procedure CheckCreated;
end;
This would allow me to write:
procedure TMyCheck.CheckCreated;
begin
if (FGuard = nil) then
begin
FObject := TObject.Create;
FGuard := TGuard.Create (FObject);
end;
end;
(for automatic lifetime management)
I know that interface fields are initialized to nil but is that also true when contained in a record?
Yes you can rely on that.
All reference-counted variables:
are initialized to
nilwhen arecordis allocated, if you useNewor a dynamic array – even locally on the stack. Of course, if you use a plainGetMemor work with pointers, you’ll have to initialize it by yourself (e.g. using aFillChar).If you are curious, there is an hidden call to the following procedure of System.pas:
This will fill all the reference-counted variables memory to 0, but won’t set the other members of the
record. In fact, in aclassinstance, the whole field memory is initialized with 0, including all members – for arecord, the initialization is only for reference-counted types.Note that in some cases, I’ve found out that this initialization was not properly generated if you use the
objecttype instead ofrecord– at least under Delphi 2009-2010. So if your code has someobjecttype declaration, you may better switch torecord(and loose inheritance), or explicitly callFillChar.If you are curious, here is an optimized version I wrote in asm – available in our enhanced RTL.