[fpc-devel] Wrong docs: not initialized global variables

Nikolay Nikolov nickysn at gmail.com
Wed Jul 4 00:00:11 CEST 2018



On 04/05/2018 05:22 PM, Karoly Balogh (Charlie/SGR) wrote:
>
>> 2.) Class fields are initialized. (Why is simple class fields
>> initialization needed for internal bookkeeping of the compiler?)
> I think this is something which happens when constructing the class, so
> this is runtime behavior, and not compile or exe loading time, and again,
> it's just clearing the allocation after GetMem()'ing the heap area for
> the class, so you don't get trash in the fields. But they're don't
> necessarily initialized to valid values (if zero is not valid).
Actually, this is done, so that you can safely free all the objects 
owned by the class safely in the destructor. If it wasn't done, instead 
of this:

constructor TMyClass.Create;
begin
   FObject1 := TSomeClass.Create;
   FObject2 := TSomeClass.Create;
end;

destructor TMyClass.Destroy;
begin
   FObject2.Free;
   FObject1.Free;
end;

you would have to do this in the constructor:

constructor TMyClass.Create;
begin
   FObject1 := nil;
   FObject2 := nil;
   FObject1 := TSomeClass.Create;
   FObject2 := TSomeClass.Create;
end;

Why? Because, if something raises an exception inside the constructor, 
the destructor will be called on the partially constructed object. And 
if the exception was raised somewhere before 'FObject2 := 
TSomeClass.Create', then, if you didn't initialize FObject2 to nil in 
the beginning, the destructor would try to free FObject2, which would be 
a random uninitialized pointer.

So, even though filling objects with zero introduces a small runtime 
overhead, it saves a lot of pain and prevents difficult to find bugs 
(people quite often don't test exceptions raised in the constructor).

Nikolay



More information about the fpc-devel mailing list