Jump to content
AlexBelo

FreeAndNil() - The Great Delphi Developer Debate

Recommended Posts

FreeAndNil() - The Great Delphi Developer Debate

https://s608.t.en25.com/e/es?s=608&e=5507850&elqTrackId=65d0dc3c5cdd4756be52277591b686f0&elq=bbc2a556cfa141cc926d04a00819b81d&elqaid=44034&elqat=1

 

OMG. What? Again? Unbelievable! :-)

 

The following MVPs have shared their opinion on the topic. Register now to see what they have to say! Allen Bauer, Dalija Prasnikar, Frank Lauter, Uwe Raabe, Paul TOTH, Radek Cervinka, Olaf Monien, Dr. Holger Flick, Patrick Prémartin, Boian Mitov, Matthew Vesperman, Vinicius Sanchez, Darian Miller, Juliomar Marchetti, Erik van Bilsen, and Nick Hodges

Share this post


Link to post

Why not? Until it's removed from the language this topic will remain important. Unfortunately I believe even if it will be eventually removed everyone will create a private copy and continue to use that as an "important tool".

Share this post


Link to post

What did I miss? What I understand is that

  1. It is not part of the language, it is just a regular method from the standard library
  2. Earlier versions did have an untyped parameter and let you pass in things that were not descendants of TObject

If that is all, how can you even have an opinion on that? What is there to talk about? Can somebody get me up to date with just one or two sentences?

 

Many thanks.

  • Like 1

Share this post


Link to post
10 minutes ago, Der schöne Günther said:

If that is all, how can you even have an opinion on that? What is there to talk about? Can somebody get me up to date with just one or two sentences?

 

My guess is that they'll try to proove that you can use free instead of freeandnil. Often you can find code:

 

var

  X: TMyImportantForm;

 

begin

   x:=TMyImportantForm.create(self);

   try

     ... some boring code ....

   finally

      FreeAndNil(x);

   end;

end;

Share this post


Link to post
24 minutes ago, Der schöne Günther said:

What did I miss? What I understand is that

  1. It is not part of the language, it is just a regular method from the standard library
  2. Earlier versions did have an untyped parameter and let you pass in things that were not descendants of TObject

If that is all, how can you even have an opinion on that? What is there to talk about? Can somebody get me up to date with just one or two sentences?

 

There is plenty to talk about. It is not just about FreeAndNil, but about constructing and destructing object and all the fine print around that process. While on the surface this topic seems simple enough and that there is nothing to talk about, it is rather complex topic and many developers, even experienced ones, easily forget about some very important facts around this topic that can cause serious issues in applications.

  • Like 3
  • Thanks 1

Share this post


Link to post
12 minutes ago, Dalija Prasnikar said:

It is not just about FreeAndNil, but about constructing and destructing object and all the fine print around that process.

Oh, in that case, absolutely. Guess I should watch it.

  • Like 1

Share this post


Link to post
34 minutes ago, Lajos Juhász said:

Often you can find code:

Often you can find code

if obj <> nil then
begin
  obj.Free;
  obj := nil;
end;

that's what FaN is for

Share this post


Link to post
7 minutes ago, Fr0sT.Brutal said:

Often you can find code

 

I never saw this kind of code, I saw:

 

if Assigned(obj) then

  obj.free;

Most of the time I only saw that a "developer" refuses to use free instead of FreeAndNil.

 

 

Share this post


Link to post
4 minutes ago, Der schöne Günther said:

Oh, in that case, absolutely. Guess I should watch it.

I am signed up. Anything I can learn ( or hear out loud and realize that I actually understand the effect of the code I am writing ) is worth my time.

This is a focused topic, I expect the content will be more focused than 'choosing the best ui framework for x' .

Share this post


Link to post
11 minutes ago, Lajos Juhász said:

 

I never saw this kind of code, I saw:

 

if Assigned(obj) then

  obj.free;

Most of the time I only saw that a "developer" refuses to use free instead of FreeAndNil.

 

 

I also use FreeAndNil - if I ever forget that an object was already freed with .Free, app might be working fine or give an AV "sometimes". When I use FreeAndNil and by mistake try to use freed object later, I am sure it always gives AV. I would not use FreeAndNil in time-critical parts, but there are almost none in my apps.

  • Like 1

Share this post


Link to post
1 hour ago, Der schöne Günther said:

Oh, in that case, absolutely. Guess I should watch it.

I mean, it can always turn out to be mindless "use this... no use that..." fighting. But without knowing the facts around object construction and destruction process, it is impossible to have an argument based discussion. 

Share this post


Link to post
2 hours ago, Fr0sT.Brutal said:

Often you can find code


if obj <> nil then
begin
  obj.Free;
  obj := nil;
end;

that's what FaN is for

Actually, obj.Free already checks for NIL, so the if statement is unnecessary.

 

FreeAndNil also does something different than the name implies:

procedure FreeAndNil(var Obj);
var
  temp: TObject;
begin
  temp := TObject(Obj);
  TObject(Obj) := nil;
  Temp.Free;
end;

(That's the old, non-typesafe version, if I remember correctly)

So it should actually be called NilAndFree because it first sets the Object reference to nil and only then calls its Free method.

 

That has some implications if there is code in the destructor / called from the destructor that references the object instance via the same pointer (which shouldn't be done but I have seen it been done.

  • Like 1

Share this post


Link to post
Posted (edited)
2 hours ago, Vandrovnik said:

I would not use FreeAndNil in time-critical parts, but there are almost none in my apps.

One additional function call and nested condition is nothing even in time-critical parts compared to heap area disposal.

29 minutes ago, dummzeuch said:

Actually, obj.Free already checks for NIL, so the if statement is unnecessary.

I know but I've seen plenty of those checks in 3rd party code

Edited by Fr0sT.Brutal

Share this post


Link to post

I use FreeAndNil, unless the object is handled by a try/finally block, or it is in a destructor.

It speeds up finding stupid mistakes in loops or singletons.

Share this post


Link to post
3 hours ago, Fr0sT.Brutal said:

I know but I've seen plenty of those checks in 3rd party code

And that takes us back to Dalija's point. Understanding needs to precede coding.

  • Like 1

Share this post


Link to post
21 minutes ago, stijnsanders said:

Let me know if this hits the mark or is way off...

var
  a:TThing;
begin
  a:=nil;//counter warning (I)
  try
    if //only in some cases
    begin
      a:=TThing.Create;
      //...
    end;
    //...
    if a<>nil then
    begin
      //use a for something
    end;
    //...
  finally
    if a<>nil then (II)
    begin
      a.Free;
      a:=nil;
    end;
  end;
end;

(I) Wrong comment. a is a local variable and doesn't have to be nil. Thus the nil is required to signal that there is no object assigned to variable a.

(II) In this code a is nil or a valid reference thus it's not required to check if it's nil that will be done in the free method.  In the next line it's not required to assign nil to a. A is a local variable and finally after the finally it will go out of scope.

Share this post


Link to post
5 hours ago, dummzeuch said:

That has some implications if there is code in the destructor / called from the destructor that references the object instance via the same pointer (which shouldn't be done but I have seen it been done.

That's a bug to use that reference, so this issue can safely be ignored with regards FAN. 

Share this post


Link to post
7 hours ago, Fr0sT.Brutal said:

 


if obj <> nil then
begin
  obj.Free;
  obj := nil;
end;

 

Amazing that there's anybody left that doesn't know that Free does the nil check itself. 

  • Like 2

Share this post


Link to post
12 minutes ago, David Heffernan said:

Amazing that there's anybody left that doesn't know that Free does the nil check itself.  

Actually, picking up on that. I could perfectly agree with if Delphi would make

obj.Free;

also set obj to nil...

Share this post


Link to post
51 minutes ago, Attila Kovacs said:

that would be wasting resources

Yeah, because delphi is so fast! But also, I doubt you could find a real program that would have a measurable performance hit even if the ref was set to nil always. 

  • Like 1

Share this post


Link to post
18 minutes ago, David Heffernan said:

Yeah, because delphi is so fast! But also, I doubt you could find a real program that would have a measurable performance hit even if the ref was set to nil always. 

At night in the cemetery, a dwarf bounces in front of the humpy and asks:
- What's on your back?
- A hump.
- Do you need it?
- No.
- Then I'll take it.
The humpy suddenly straightens, happily seeing that he is no longer crippled. He hurries home and meets the lame and tells what happened to him. The lame immediately rushes to the cemetery, searching for the dwarf.

The dwarf jumps in front of him and asks:
- What's on your back, lame?
- Nothing...
- Then get it, here's a hump!
 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×