Thursday, April 2, 2009

Forcing RTTI on record types

While developing the “Type Support” module for the generics library I’m working on I’ve encountered a little problem - the compiler will not emit RTTI information for the records. Actually that isn’t entirely true - RTTI will be emitted if a record contains a “managed type” like dynamic arrays, strings, interfaces or reference to functions. The compiler needs that RTTI on records because it needs to initialize and finalize those managed types.


Now, back to our problem. Why would you need RTTI on a record in the first place? Well, in my case the I’ve added a possibility to register custom “type support” classes for any of your custom data types (which happen to be records). To be able to retrieve those classes later the TypeInfo is required to be unique for those data types which also means it must exist!


After some fiddling around, I’ve come up with a hacky way to force the compiler to emit RTTI on my records. Check out the code below:



uses
SysUtils, TypInfo;

type
TMyRecord1 = record
strict private
FForceRTTI: IInterface;
public
{ ... Any fields you want here ...}
end;

begin
WriteLn(PTypeInfo(TypeInfo(TTypeInfo))^.Name);
Readln;
end.

Notice the strict private FForceRTTI field that is of type IInterface. It ensures that the compiler knows that we have a “managed type” in our record so it will emit RTTI information for it! The disadvantage of this little hack is that the compiler will be forced to add initialization and finalization code each time you are using this record in your code. It will do that to ensure that the FForceRTTI field is always reference counted and deallocated when requuired. Until the compiler team adds support for records in RTTI this hack will do.

No comments: