> > 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
