> > Couldn't they have used a "var Obj:TObject" instead? Would
> there be a
> > problem with passing "nil" objects to that proc then? I wonder why
>
> No, because the compiler requires an the 'var' parameter is
> of exact same type, it can't even be a descendant :-(

It does indeed. Hadn't ever needed such a thing so didn't notice it.

One could use a PObject param instead of a "var" instead, but then they'll
have to use @ to pass an object to SafeFreeAndNil. Another interesting thing
also, is that both x^.Free and x.Free work (the button disappears when
SafeFreeAndNil gets called at the button's event handler), seems the Delphi
compiler treats pointers to objects as the objects themselves or something
like that. Of course x:=nil wouldn't also do the same as x^:=nil at the next
line.

type PObject=^TObject;

procedure SafeFreeAndNil(x:PObject);
begin
 x^.Free; //seems x.Free also works!
 x^:=nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
var x:TButton;
begin
 x:=button1;
 SafeFreeAndNil(@x);
 x.Caption:='A';
end;

The x.Caption:='A' doesn't throw a runtime error at Delphi7, which made me
wonder why. So I added

 if x=nil then
  x.caption:='nil';

right after
 SafeFreeAndNil(@x)

And it even hit the breakpoint and I stepped and executed the line
x.caption:='nil' even though x was nil (cause of the "if" statement).
Changing x^:=nil to x:=nil of course made it not hit that breakpoint

I even noticed that with x^:=nil (which is the correct thing to have) for
SafeFreeAndNil to do its job, if one adds a Label on the form, they get an
EAbstractError with no more details after SafeFreeAndNil is called. Not sure
why, most probably cause the event handler of Button1 kills Button1 and
there's some problem with the stack then when the event handler returns or
with message passing. This seems to bite only if there are more than one
controls on the form.

The following seems to work fine


type PObject=^TObject;

procedure SafeFreeAndNil(x:PObject);
begin
 x^.Free; //seems x.Free also works!
 x^:=nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
var x:TLabel;
begin
 x:=label1;
 SafeFreeAndNil(@x);
 button1.Caption:='A';
end;

Although if I use x.Caption:='A' it doesn't throw an error (even though x is
nil). Have to use the /cpu view I suppose to see what Delphi7 compiler
generates there (it's not the first strange behaviour with borland's pascal
compilers that I've seen over the years [using them since arround 1990])

> > As it is now it does very bad crash if you pass by accident say an
> > interface reference to it instead of an object reference
> (can easily
> > do this mistake if one reengineers their code to use
> interfaces - they
> > may forget to remove the FreeAndNil stuff, thus getting bad runtime
> > crashes instead of a compiler message that a TObject descendent is
> > needed as param to FreeAndNil)
> >
> > Is FreePascal using "TObject" there or a "var Obj" param too?
>
> I've just checked (version 2.0.2) and it indeed is
> implemented like Delphi :-( But as a matter of fact it could
> have been implemented the right way, because FPC does the
> sane thing and allow descendants as 'var'
> parameters.

Since object references are just pointers, I suppose FPC does correctly, so
Lazarus could use the "var:TObject" version of FreeAndNil

procedure FreeAndNil(var x:TObject);
begin
 if x<>nil then x.Free;
 x:=nil;
end;

One might say you don't need to check for nil, Free must be checking it too,
but not sure which is worse, an extra <>nil check or one unneeded call to
Free (I suppose the 2nd is worse, although with Delphi passing params using
registers by default instead of using the stack I'm not sure)

> Yerder yet there's a 'FreeThenNil' function in LCLProc which
> calls obj.Free before setting the pointer to null :-/

Why is there a "FreeThenNil" too apart from "FreeAndNil". Is it supposed to
do something different?. Not sure if the order there plays any role. I
suppose it should be the Borland order so that possibly some very
play-it-clever static code analysis tools doesn't complain

----------------
George Birbilis ([EMAIL PROTECTED])
Microsoft MVP J# for 2004-2006
Borland "Spirit of Delphi"
* QuickTime, QTVR, ActiveX, VCL, .NET
http://www.kagi.com/birbilis
* Robotics
http://www.mech.upatras.gr/~Robotics
http://www.mech.upatras.gr/~robgroup




  _____  

avast! Antivirus <http://www.avast.com> : Outbound message clean. 


Virus Database (VPS): 0625-7, 23/06/2006
Tested on: 23/6/2006 11:25:06 ??
avast! - copyright (c) 1988-2006 ALWIL Software.



_________________________________________________________________
     To unsubscribe: mail [EMAIL PROTECTED] with
                "unsubscribe" as the Subject
   archives at http://www.lazarus.freepascal.org/mailarchives

Reply via email to