On Not Using FreeAndNil

This post was originally published on December 13, 2011.  I consider it a classic.

There has been a large and ongoing thread in the Delphi Non-Technical newsgroup about the proper use of FreeAndNil.  It’s been contentious and a tad touchy, too — just as I like it. 🙂 The discussion falls out into two schools of thought:  Those that use FreeAndNil liberally and almost everywhere, and those that use it not at all or only in very rare, specific cases.  The former argues it is “defensive coding”, while the latter argues that it is the coding equivalent of spraying perfume on a skunk.

I am in the latter camp.  I am in the latter camp for a very good reason:  because the latter camp is right.  Winking smile There’s almost never a reason to use FreeAndNil in the new code that you write.

And I want to be clear about that – I’m talking specifically about new code.   If you have old code that was designed in such a way that the scope of your pointers wasn’t tightly contained, then yes, you’ll probably have to use FreeAndNil to make that code work right.  But if you are doing that, I hope that you recognize that it is a problem and plan to refactor the code to contain the scope of your pointers.   I’m totally aware that legacy code may very well require that you nil pointers because the scope of those pointers is not well managed.  I know this because our system has such code, and thus contains calls to FreeAndNil.

So, anyway, here’s an explanation of why I think that FreeAndNil should only be used very, very sparingly.

Before I start, I want to add that this blog post is heavily influenced by the eloquent wisdom and excellent explanations of a number of people who participated in the thread, including Bob Dawson, Wayne Niddery, Rudy Velthuis, Joanna Carter, Mark Edington, and Pieter Zijlstra.  Any profundity, excellent examples, pithy similes, or clear descriptions of things are very likely a result of me reading their posts in the thread.

Introduction

FreeAndNil is a function declared in the SysUtils unit and was introduced in Delphi 4, if I recall correctly.  I myself suspect that it was added more because of customer demand than because the R&D Team felt some need for it, and I’m reasonably sure that if they had it to do over again, they would not have added it at all.  But there it is.

The code for FreeAndNil is as follows:

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

That does seem a bit weird looking – you might expect it to look like this:

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

But it doesn’t.  It looks the way it does for a couple of reasons.  First, the parameter passed needs to be a var parameter because two things need to happen.  The object referenced needs to be freed, and the reference itself needs to be altered  — that is, set to nil.  Thus, you need the freedom to change both the reference and the thing being referenced that the var parameter gives.  Second, the parameter is untyped because when you pass a var parameter, “Types of actual and formal var parameters must be identical.” Given that, if you declared the parameter as a TObject, then you could pass only a TObject to the method and not any of its descendants.

For instance, the following code will not compile:

program WontWork;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type

  TMyClass = class(TObject);

procedure Foo(var Obj: TObject);
begin
  WriteLn(Obj.ClassName);
end;

var
 MyClass : TMyClass;

begin
  MyClass := TMyClass.Create;
  try
    Foo(MyClass);
  finally
    MyClass.Free;
  end;
end.

I should point out that the use (or non-use) of FreeAndNil is not an insignificant and uncontroversial issue.  The thread that spawned this is typically long.  Allen Bauer, the Chief Scientist at Embarcadero, blogged about it, and quite a discussion ensued in the comments – so much so that he felt the need to blog about it again.  StackOverflow has a whole bunch of questions on the subject.  The VCL uses FreeAndNil in places that I wouldn’t necessarily approve of.   I think that in most places its use indicates, uhm, an “older” design choice that probably wouldn’t be made today, given newer language features.  In any event, clearly folks have strong views on this and that the use (or note) of FreeAndNil is not “settled science” (though I believe it should be…).

Okay, So When Should You Use FreeAndNil?

In my mind, the answer to the question “When should I use FreeAndNil?” is “never”, or at least “Almost never, and if you must use it, make sure that there is a really, really good reason to do so and that you clearly document that reason”.  I myself have never (to my best recollection – I fully expect someone to find some obscure reference to code I wrote years ago that uses it….) used the procedure and see no possible scenario where I would want or need to in the code I write.  My recommendation is that you never use it either because I don’t believe that you are writing code that needs it either (unless you are on the Delphi R&D team working in the bowels of the RTL, I suppose).

Why I Don’t Use FreeAndNil and Why You Shouldn’t Either

There are a number of reasons why I don’t use FreeAndNil.

First, a call to Free is sufficient. It gets the job done.  Free will, well, free the memory associated with your reference.  It does the job completely and totally.  Can’t do any more.  Setting a pointer to nil doesn’t get you anything.  The memory isn’t going to be more free or freed faster as a result of calling FreeAndNil.  Since it’s always a good practice to use exactly the right tool and nothing more, there’s no need to make the extra call.  Consider this – there’s no SetToZero call for integers, and if there were, why would you use it?  All code should be written with “considered intent,” and the indiscriminate use of FreeAndNil shows a lack of consideration and intent.

Second, using FreeAndNil where Free alone will do just fine obfuscates your code.  Using a call that executes unneeded instructions sends a message to future readers of the code that shouldn’t be sent.  A subsequent developer maintaining your code might look at the call and say “What the heck?  Why is FreeAndNil being used here and not just Free?  Is something going on here that I don’t know about?”  Time might then be wasted investigating, and a satisfactory answer may never be found.   Code that uses Free and FreeAndNil as exactly the same thing has reduced the amount of information that your code can convey.  And when you are dealing with something as important as memory management, you certainly don’t want to reduce the amount of information your code can convey.

FreeAndNil has a clear meaning – it is a very clear indicator that the pointer being freed has meaning outside of the scope where it is used.  If it doesn’t say that, then you shouldn’t use it.  If you use FreeAndNil when that is not the case, then you’ve sent a bad message to future maintainers.  Clarity in code is paramount – nothing should be done to decrease that clarity.  Code should be intentional and there for a reason.  Code that is there that doesn’t need to be can be misleading and distracting.  Misleading and distracting are not two thoughts that developers want crossing their minds while maintaining code.

Free has meaning as well – it clearly states that the use of that pointer reference is now done and over with.  As noted above, there’s no need to call anything else.  The indiscriminate use of FreeAndNil fails to draw the clear distinction between Free and FreeAndNil.  Losing clarity in your code is bad, right?

Third, one of the justifications for using FreeAndNil is that it is defensive and that it protects against using a pointer at the wrong time.  The claim is that if a pointer is nil, and you then use that pointer, then you’ll know right away, and the bug would be easy to find. Thus, if you feel the need to use FreeAndNil to ensure that you don’t misuse a pointer somewhere, then it is very likely you have a design problem:  the scope of the pointer in question is larger than the use of that pointer in your code.  Or, in other words, the scope of a pointer and the scope of the use of that pointer aren’t the same and they should be.  If they aren’t , you are simply begging for trouble.

If you want to really be persnickety, a variable that is broader in scope than it’s use is a form of a global variable.  And I would hope that we agree that global variables are bad.  If we can’t agree on that, well, then we can’t agree on anything.  Winking smile

Maintaining proper scope is critical to good, clean code.  I’ve discussed this before, and so I won’t go on about it here.  The germane point here is that if the scope of a pointer is of the “laying around waiting to be used”, then there is no limit to the mischief that this wayward pointer can cause.  So, if you don’t “leave a pointer lying around”, you can’t misuse it.  So, well, don’t leave a pointer lying around.   If you don’t leave roller skates at the bottom of the stairs, you can’t go careening down the hallway.   Keep your pointers and the use of those pointers in the same scope and you can’t misuse a pointer.  And you won’t feel the need to use FreeAndNil.

And if you do use it for defensive reasons, you have to use it everywhere.  You have to use it in ever single place it is needed and you can’t miss a single place.  And, every single maintainer of the code after you has to as well.  One instance of not using it basically removes all the reasons for using it.  It’s a much better plan to simply control your scope and never feel the need for it.

So, in the end…

In the end, I guess the argument for using FreeAndNil seems to boil down to:

“Of course I use FreeAndNil – it protects against bugs and makes other bugs easy to find, and besides, what’s the harm?”

Well, it would seem that none of those reasons is really true.  The real argument is:

“If your code requires you to use FreeAndNil to reveal and easily find bugs, then your design is wrong.  Good, clean code never feels the need to worry about errant pointers.”

Hey, look: design your code however you like. However, if you were to ask me, I’d say to design your code in such a way that FreeAndNil sends no signal, doesn’t find any bugs any sooner, doesn’t protect against anything, and thus becomes utterly superfluous.

Book Stuff

As always, I’m very grateful to all of you who buy my books.  Thank you.

But here’s something interesting about my books:  Coding in Delphi sells more than More Coding in Delphi and Dependency Injection in Delphi.

That means that there are many of you out there who have bought one of my books, but not the others. Now, maybe you guys buy Coding in Delphi, don’t like it, and then never come back for more.  Fair enough.

But I’m wondering if it’s because you just don’t know that the other two books exist?

I’m no marketing expert — that’s clear — but I’m not above posting a blog entry shamelessly pointing out that I have two other books and that I think you should buy them.  😉

nickhodges.com Will be Changing

Okay, so I have successfully migrated the content from nickhodges.com over to this blog.  As a result, I’m going to be altering what is on nickhodges.com, making it a bit more of a personal site advertising my wares, projects, interests, and what-not.  In fact, I’m going to be doing that today — so this isn’t much heads up, but I’m guessing that won’t bother anyone — the site doesn’t really get much traffic.

As always, thanks for reading.

Book Price Drop….Again!

Hey, my book prices are dropping again:

Links to both LeanPub, where you can by electronic copies, and Amazon, where you can buy hardcopies, are here at http://codingindelphi.com/

It might take a bit for the prices to propagate, but I wanted you to know ASAP.  Get ’em while they’re hot! 🙂

Me on medium.com

Hey —

This blog is fun and I hope educational, but it reaches only a certain spectrum of the developer community — that is, almost all of you are Delphi developers. I’m grateful to every one of you that has read my blog and bought my books, but I wanted to try to reach out to a broader audience with my writing.

So, I started writing on medium.com. If you aren’t familiar with Medium, then you might want to consider giving it a look. Medium is a huge blogging platform, with many publications of all types. It has both a free version and a paywall version, and the cost is a mere $5 a month. I started writing all different kinds of things but was lucky enough to be picked up as a writer by Better Programming. I’ve published a number of different technical articles there, which are listed below. I’ve managed to even make a little money via the Medium Partner Program.

Readers of my books will notice some of the content — I’ve reused a lot of what I wrote in my books and published it for a non-Delphi crowd. (Note that if there was code to show, I used TypeScript.)

Okay, so if you want to read my latest stuff on Medium, here’s a list of links. I’d be grateful if you gave a look at anything that you find interesting:

Flotsam and Jetsam #121

  • Goodness, I’ve been neglectful of this blog.
  • I have a problem, and I’m hoping you all can help me. Almost five years ago, I left my BlogEngine.net-based blog at http://nickhodges.com/ and moved my blog to here. I have a lot of content there, and a lot of links that still get viewed. I’d like to do something more useful with nickhodges.com, But I don’t want to lose the content. Losing the links would be slightly less worrisome if the content were still discoverable. BlogEngine.net is pretty much abandoned and has no good export capability, other than BlogML which is so old that no one imports it. I’m not thrilled at having to write an application to read the BlogML output and convert it to some useful format. Does anyone have any ideas?
    • In a classic “Talk to the duck” moment, after writing the above, I found this blog post that pretty much already wrote the utility for me. I gave it a shot but didn’t have much luck. It said it imported something, and some of the stuff is there, but it didn’t have the desired effect. Maybe I’m missing something…..
  • Okay, so I just noticed that my book More Coding in Delphi was priced at $29.99, higher than Coding in Delphi by $5.00. I’ve lowered the former so that both are the same price. Please feel free to buy it.
  • I am, of course, grateful to all of you who have bought my books. I have, however, noticed an interesting trend. Coding in Delphi continues to sell better than the other two books, even after all these years. That means that there are a lot of you out there who are buying Coding in Delphi, but not buying More Coding in Delphi and Dependency Injection in Delphi. You can, of course, buy the two newer books. I won’t stop you. 😉
  • And if you want to buy more than one, there are bundles available on LeanPub — one for my first two books, and one for all three. Don’t be shy!
  • (And yes, the last three bullet points were just an excuse plug my books and to link to them on Amazon and LeanPub. I’m shameless.)

Gateway Ticketing Needs Delphi Developers

Gateway Ticketing is hiring. Things are going really well, and we need to expand what we are doing. We are looking for developers — Delphi developers specifically, but we are mostly interested in smart people that know what they are doing when developing high-quality software.  We love Delphi and C#, but in the end, those are just languages and we know that it doesn’t ultimately matter what tool you know, but whether you really know how to write clean code.

Here are some reasons why you should consider working for Gateway Ticketing:

  • We are a great place to work.  I love it here.  We have a great group of people and a great culture. 
  • We are serious about being serious about software development.  We aren’t messing around here.  While we have a large legacy code base, we are all about doing the right thing the right way with the right tools.  We insist on unit tests for your code.  We insist that you keep up with the latest innovations in writing code.  We insist that you view coding the same way that Rembrandt viewed painting.   We are not messing around here.
  • We love Delphi, and we live and  breathe it here.  We are doing cool things like using the Delphi Spring Framework and other fun stuff.
  • We are writing RESTful APIs to build the ticketing system of the future.
  • We use C# and ASP.NET for our eCommerce solution and all the cool stuff that goes along with that.
  • We are located in beautiful Gilbertsville, Pennsylvania.  This a great place to live and raise a family.  We are close to everything but have that great small town feel.  I love living here, and you will too.
  • Our customers are some of the greatest and most fun places on earth.  We sell systems to the largest amusement parks, zoos, water parks, and museums all over the world.  This is a cool industry.  Who doesn’t love a good amusement park?

Okay, look – everyone says they want to hire “rock-star developers”.  That’s all well and good, but the bottom line is that we are setting our standards really high.  And if doing that scares people off, well so be it.  We don’t want people who are scared off by high standards.  We want people who are looking for places with high standards.  We expect and demand your very best – anything less and you should find a job writing VB code. We really are creating a world-class place to build software, and we want folks like you to be a part of it.  You are up for that, right?

And of course, here are the obligatory caveats. Naturally, you must be eligible to work in the United States.  Relocation assistance is available. Remote work within the US is available for the right candidate.  We don’t care where you are from or who your parents were or what color your dog is or anything like that.  We are really only interested in what you can do.  And of course, we want you to know what we can do for you, too.

Sorry, we cannot sponsor H1B visas.

If that sounds like something good to you, please email me at nickhodges@gmail.com.

Code for DIID Updated

UPDATED:  I see now that my friend Kirk Halgren is the mystery man.  Thanks, Kirk!

Thanks to the comment of a generous reader — whom I am ashamed to say I can’t remember — I have updated the code for Dependency Injection in Delphi to remove all the uses of the GlobalContainer.  

The book removed it all, but I failed to properly update the repository.

You can get the corrected code on BitBucket.

Amazon

Look, I’m not a lawyer. I don’t know anything about anti-trust law that I haven’t read online or see on TV or whatever. But I just read about six articles in the New York Times about Amazon, and all of them have the tone that Amazon is this close to a lawsuit from the Department of Justice or the EU.

I think that’s crazy.

I don’t think it is crazy that governments will be after Amazon — that seems inevitble — I think it is crazy that anyone thinks Amazon is doing anything wrong.

I’m a big fan of Amazon. I shop there. I use their credit card to get discounts on products I buy online and at Whole Foods. Shoot, an Amazon gift card is just about as good as cash as far as I’m concerned. I’m a fanboi, I admit it.

Why? Well, because Amazon is a ridiculously good place to get stuff. It is the first place I go when I want something. It sets the bar for pricing and choice. There’s are reasons for that: It’s cheap. It’s convenient. It’s always there. It’s fast. They deliver to my house, usually the next day. They have terrific user reviews. They deliver great video content into my house. They seem to know what I want before I want it. They give me great, targeted ads for things I’m thinking about buying. It’s just so frigging amazing. Why wouldn’t I feel this way?

Well, some folks don’t agree. One woman, Lina Khan,  thinks that Amazon is a monopoly because they are making things cheaper. Huh?  

If anti-trust does anything — and I don’t think it should do anything, but that’s another post — it should protect consumers, not competitors.  If Amazon provides great products and great services and great prices, everyone is better off.

Amazon is providing incredible value to the marketplace. Sure, they are very likely affecting other retail companies, but guess what: That’s what capitalism is all about. Amazon has built a better mouse-trap, and now the world is beating a path to their door. What a stunning surprise.

I don’t get the angst about what they are doing. They are challenging Google in the advertising space — that is, they are making the advertising market more competitive. They are lowering prices at Whole Foods, while offering discounts to Prime members. They are pressing other retailers like Target and Nordstroms to modernize and provide better service at better prices. This is a bad thing?

Uhm, no, it’s not. It’s how it is supposed to work.  Companies compete with each other and make each other better.  Competition is the only thing that motivates companies to get better.  Amazon is providing a lot of competition, and everyone is better off because of it.

If you want to jump on Amazon about anything, jump on them about the working conditions of their warehouse workers. I don’t know what the overall situation is for sure, but it does seem to be that some workers are not being treated well. If that is the case, then get on Amazon about that, and not with the threat of some government regulation, but with the real threat of not buying from them until things get better and the real threat of bad publicity. That’s what really will motivate them.

They won’t mind government regulation that much as it generally serves merely to make it harder to compete with them. They have the money to deal with onerous government regulation. And upstart competitor does not.

In the end, Amazon provides enormous social value. The company just passed the $1,000,000,000,000 mark in valuation. You don’t get that way buy doing anything other than providing huge social value and giving customers what they want.