in objpas.inc there is the following code for TObject
procedure TObject.Free;
begin
// the call via self avoids a warning
if self<>nil then
self.destroy;
end;
what i want to ask is - does the line
if self<>nil then
has any effect? i mean, if self is nil then a call to Free looks like nil.Free and it will fail because Free is a normal method of an uninitialized object, not a class method.
Finally, could this code be reduced to
procedure TObject.Free;
begin
// the call via self avoids a warning
self.destroy;
end;
without loss of functionality?
AFAIK, the compiler gets this code:
PROCEDURE TObject.Free;
BEGIN
// the call via self avoids a warning
IF SELF <> NIL THEN
SELF.Destroy;
END;
...
Object.Free;
...
and translates it to:
PROCEDURE _TObject_Free_ (SELF: TObjecPtr);
BEGIN
// the call via self avoids a warning
IF SELF <> NIL THEN
SELF^.TObject_VirtualTable.Destroy^ (SELF);
END;
...
_TObject_Free_ (Object);
...
.
That's why it checks if SELF is NIL.
Note: I know, I know, it doesn't do it in this exact way, but it's a simplification.
[edit] After read Martin_fr's explanation again:
TObject (NIL).Free;
is translated to
_TObject_Free_ (TObjecPtr (NIL));
but
TObject (NIL).Destroy;
is translated to
TObjecPtr (NIL)^.TObject_VirtualTable^.Destroy (TObjectPtr (NIL));
That's why the first doesn't generates a runtime error but the last does it, and also explains why "Free" is recommended.