Global managed record variable isn’t initialized if not referenced in the same unit.
...And, conversely, always initialized even if its referencers aren’t called by anyone (though the latter might be by design, as it is at least always and consistently finalized, even with empty main :D).
Example:
main_program.pas
{$mode objfpc} {$longstrings on}
uses
UnitA;
begin
Con.Dump('Main');
end.
UnitA.pas
{$mode objfpc} {$longstrings on} {$modeswitch advancedrecords}
{$define enable_UseFromA}
unit UnitA;
interface
type
Console = record
Initialized: boolean;
procedure Dump(const where: string);
class operator Initialize(var self: Console);
class operator Finalize(var self: Console);
end;
{$ifdef enable_UseFromA}
procedure UseFromA;
{$endif}
var
Con: Console;
implementation
procedure Console.Dump(const where: string);
begin
if not Initialized then write('/UNINITIALIZED/ ');
writeln(where);
end;
class operator Console.Initialize(var self: Console);
begin
writeln('Console.Initialize');
self.Initialized := true;
end;
class operator Console.Finalize(var self: Console);
begin
self.Initialized := false;
writeln('Console.Finalize');
end;
{$ifdef enable_UseFromA}
procedure UseFromA;
begin
Con.Dump('UseFromA');
end;
{$endif}
end.
Output without enable_UseFromA
:
/UNINITIALIZED/ Main
Console.Finalize
Output with enable_UseFromA
:
Console.Initialize
Main
Console.Finalize
Note that in the second case, UseFromA
is not called by anyone and even (or should I say “of course”) absent from the binary.
Edited by Rika