Recent

Author Topic: Why is FreeAndNil implemented "backwards", exactly?  (Read 11000 times)

Paulo França Lacerda

  • New Member
  • *
  • Posts: 44
    • BlaisePoint Informática
Re: Why is FreeAndNil implemented "backwards", exactly?
« Reply #15 on: October 03, 2016, 09:26:16 pm »
Oops... I get a false-positive here when passing a pointer:
.
Code: Pascal  [Select][+][-]
  1.   if O is TObject then...   // this works with FPC, but generates a false-positive under Delphi.
.
In my tests, only the following works as expected (both under FPC and Delphi):

Code: Pascal  [Select][+][-]
  1. if O.InheritsFrom(TObject)...
« Last Edit: October 04, 2016, 04:01:03 am by Paulo França Lacerda (patulinu) »
Lazarus 1.6.0.4 on FreePascal 3.0
Windows 7 32-bit

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Why is FreeAndNil implemented "backwards", exactly?
« Reply #16 on: October 05, 2016, 09:23:29 pm »
Just 1 note on the topic that is good to know. Don't use global vars inside class that refer to same object you are about to destroy.
Code: Pascal  [Select][+][-]
  1. type
  2.   TTestClass = class
  3.     n: integer;
  4.     procedure DoSomething;
  5.     destructor Destroy; override;
  6.   end;
  7.  
  8.   TForm1 = class(TForm)
  9.     Button1: TButton;
  10.     procedure Button1Click(Sender: TObject);
  11.   private
  12.   public
  13.   end;
  14.  
  15. var
  16.   Form1: TForm1;
  17.   tc: TTestClass;
  18.  
  19. implementation
  20.  
  21. {$R *.lfm}
  22.  
  23. procedure TTestClass.DoSomething;
  24. begin
  25.   form1.Caption:=inttostr(n);
  26. end;
  27.  
  28. destructor TTestClass.Destroy;
  29. begin
  30.   // normally without "tc."
  31.   tc.DoSomething;
  32.   inherited Destroy;
  33. end;
  34.  
  35. procedure TForm1.Button1Click(Sender: TObject);
  36. begin
  37.   tc:=TTestClass.Create;
  38.   FreeAndNil(tc); // Sigsegv!
  39.   //tc.Free; tc:=nil; // This sequence works
  40. end;

totya

  • Hero Member
  • *****
  • Posts: 577
Re: Why is FreeAndNil implemented "backwards", exactly?
« Reply #17 on: October 05, 2016, 10:25:05 pm »
Hi!

I didn't get sigsev with your demo. Otherwise... you shouldn't use FreeAndNil in that way, the right way is long time ago:

Code: Pascal  [Select][+][-]
  1. if Assigned(SampleObject) then
  2.    FreeAndNil(SampleObject);

But it need too (long time ago), when you create object:

Code: Pascal  [Select][+][-]
  1. SampleObject:= nil;
  2. SampleObject:= TSampleObject.Create;
  3.  

and then you can test:

Code: Pascal  [Select][+][-]
  1. if Assigned(SampleObject) then

Thaddy

  • Hero Member
  • *****
  • Posts: 10186
Re: Why is FreeAndNil implemented "backwards", exactly?
« Reply #18 on: October 10, 2016, 02:44:37 pm »
Oops... I get a false-positive here when passing a pointer:
.
Code: Pascal  [Select][+][-]
  1.   if O is TObject then...   // this works with FPC, but generates a false-positive under Delphi.

WHICH Delphi version, because that is valid code and I usually test at least D7 and XE2.
Btw: You did not ask for Delphi compatibility.....
I am more like donkey than shrek

Paulo França Lacerda

  • New Member
  • *
  • Posts: 44
    • BlaisePoint Informática
Re: Why is FreeAndNil implemented "backwards", exactly?
« Reply #19 on: October 15, 2016, 09:11:54 pm »
Oops... I get a false-positive here when passing a pointer:
.
Code: Pascal  [Select][+][-]
  1.   if O is TObject then...   // this works with FPC, but generates a false-positive under Delphi.

WHICH Delphi version, because that is valid code and I usually test at least D7 and XE2.
Delphi 7, and it's unstable. Sometimes it generates the false-positive, sometimes it works as with FPC.
« Last Edit: October 15, 2016, 09:13:57 pm by Paulo França Lacerda (patulinu) »
Lazarus 1.6.0.4 on FreePascal 3.0
Windows 7 32-bit

 

TinyPortal © 2005-2018