Recent

Author Topic: pascal language lesson 2  (Read 6052 times)

cd

  • Jr. Member
  • **
  • Posts: 54
pascal language lesson 2
« on: February 16, 2010, 12:13:52 pm »
in objpas.inc there is the following code for TObject
Code: [Select]
      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
Code: [Select]
           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
Code: [Select]
      procedure TObject.Free;
        begin
           // the call via self avoids a warning
             self.destroy;
        end;
without loss of functionality?

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: pascal language lesson 2
« Reply #1 on: February 16, 2010, 12:31:13 pm »
Hm, maybe the comment explains it?
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9909
  • Debugger - SynEdit - and more
    • wiki
Re: pascal language lesson 2
« Reply #2 on: February 16, 2010, 01:15:32 pm »
Free is not a virtual method, so self can be nil.

you can not do
nil.free;

because nil isn't typed.
but

TObject(nil).Free;
will work.
 (as will any variable.free, if variable is of type TObject or descendand, even if variable is nil.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: pascal language lesson 2
« Reply #3 on: February 17, 2010, 09:41:50 am »
in objpas.inc there is the following code for TObject
Code: [Select]
      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
Code: [Select]
           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
Code: [Select]
      procedure TObject.Free;
        begin
           // the call via self avoids a warning
             self.destroy;
        end;
without loss of functionality?

AFAIK, the compiler gets this code:
Code: [Select]
   PROCEDURE TObject.Free;
   BEGIN
   // the call via self avoids a warning
      IF SELF <> NIL THEN
         SELF.Destroy;
   END;
...
  Object.Free;
...

and translates it to:
Code: [Select]
   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:

Code: [Select]
TObject (NIL).Free; is translated to
Code: [Select]
_TObject_Free_ (TObjecPtr (NIL));
but
Code: [Select]
TObject (NIL).Destroy; is translated to
Code: [Select]
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.
« Last Edit: February 17, 2010, 10:22:34 am by Ñuño_Martínez »
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

 

TinyPortal © 2005-2018