[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