Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Assigned and FreeAndNil

833 views
Skip to first unread message

John Jacobson

unread,
Oct 26, 2006, 12:45:14 AM10/26/06
to
I have a disagreement with a fellow programmer about how FreeAndNil works in
Win32 Delphi. He keeps insisting that we need to put "if Assigned(x) then"
in front of every call to "FreeAndNil(x)". I say that we don't need to,
because FreeAndNil(x) will do the test for nil in the Free code that gets
called.

What think ye? In teh valued opinion of the readers of this fine newsgroup
is this...

if Assigned(x) then FreeAndNil(x);

...actually any safer than

FreeAndNil(x);

?

--
John M. Jacobson
Jake's Blog on Delphi and Programming: http://blogs.slcdug.org/jjacobson/
Intelligent Debate: http://debunkingchristianity.blogspot.com/


Finn Tolderlund

unread,
Oct 26, 2006, 1:02:54 AM10/26/06
to

"John Jacobson" <jake@j[nospam]snewsreader.com> skrev i en meddelelse
news:45403d57$1...@newsgroups.borland.com...

>I have a disagreement with a fellow programmer about how FreeAndNil works
>in Win32 Delphi. He keeps insisting that we need to put "if Assigned(x)
>then" in front of every call to "FreeAndNil(x)". I say that we don't need
>to, because FreeAndNil(x) will do the test for nil in the Free code that
>gets called.

You are correct.
The Free method does a if Assigned, so testing for Assigned achieves
nothing.
--
Finn Tolderlund


Kryvich

unread,
Oct 26, 2006, 1:27:16 AM10/26/06
to
Look at SysUtils.pas and System.pas:

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

procedure TObject.Free;
begin
if Self <> nil then // <<-- Here goes the testing
Destroy;
end;


Rick Beerendonk

unread,
Oct 26, 2006, 3:08:25 AM10/26/06
to
> What think ye? In teh valued opinion of the readers of this fine newsgroup
> is this...

Fire the other programmer <g>

Rick


Bob Dawson

unread,
Oct 26, 2006, 8:30:06 AM10/26/06
to
"John Jacobson" wrote
>
> What think ye?

Since it's not a serious question (use the source, Luke), I think you're
collecting data for a blog post <g>

bobD


John Jacobson

unread,
Oct 26, 2006, 8:44:38 AM10/26/06
to

"Bob Dawson" <bda...@idtdna.com> wrote in message
news:4540...@newsgroups.borland.com...

I DID use the source, and even showed it to this other programmer. He STILL
insisted that we HAVE to put "if Assigned(x) then" in front of our
FreeAndNils.


Rick Beerendonk

unread,
Oct 26, 2006, 9:07:32 AM10/26/06
to
> I DID use the source, and even showed it to this other programmer. He
> STILL insisted that we HAVE to put "if Assigned(x) then" in front of our
> FreeAndNils.

That's why I said: Fire the guy. He not only writes slower and less
maintainable software, but silly discussions like this also "cost time".

Rick


Robert Giesecke

unread,
Oct 26, 2006, 9:04:03 AM10/26/06
to
John Jacobson wrote:
> Bob Dawson wrote

>> Since it's not a serious question (use the source, Luke), I think you're collecting data for a blog post <g>
>
> I DID use the source, and even showed it to this other programmer. He STILL insisted that we HAVE to put "if Assigned(x)
> then" in front of our FreeAndNils.

You mentioned that before... I think in your "WTF" thread, right?

Funny thing is, that a lot of Delphians think of FreeAndNil as some magic silver bullet.
They even use it inside destructors or at the end of a method[1].
Maybe even cross fingers and jump 3 times in circle to complete the spell, which shall save them from evil memory-leaks. *g*

[1]where there's no way to check a reference afterwards against nil, because there is no reference anymore *g*

Rick Beerendonk

unread,
Oct 26, 2006, 9:10:50 AM10/26/06
to
> They even use it inside destructors or at the end of a method[1].

I do that so I don't need to touch that code again when extra code is added
at the end of the method (f.e.)

Rick


Message has been deleted

Bob Dawson

unread,
Oct 26, 2006, 9:31:32 AM10/26/06
to
"John Jacobson" wrote

>
> I DID use the source, and even showed it to this
> other programmer. He STILL insisted that we
> HAVE to put "if Assigned(x) then" in front of our
> FreeAndNils.

Then I'm impressed at your tolerance (or your current dosage). The Jake I
knew did not suffer fools gladly...<g>

Now if you rephrased the question slightly and said "Is there any
conceivable advantage to the pattern 'if Assigned(x) then FreeAndNil(x)'"
then the answer would change. 'If assigned' avoids two unnecessary nested
procedure calls if x is nil to start with, though it does that at the
expense of a redundant check if the x is not nil. Nevertheless, I suppose
(without testing) that it could be infinitesimally more efficient than
always calling FreeAndNil IF it could be shown that x is indeed nil a
sufficient percent of the time for the specific routine where the assigned()
check is being made. That sort of optimization is also quite foolish, of
course.

No other advantage occurs to me off the top of my head--the assigned check
doesn't even provide any additional type safety. The follow abomination
compiles quite happily, for example:

type
ThsRec = record
int : integer;
end;

procedure TForm1.Button1Click(Sender : TObject);
var
rec : ThisRec;
prec : pointer;
begin
prec := @rec;
if assigned(prec) then
FreeAndNil(prec);
end;

Of course, it doesn't run very well ...

bobD


Roger Lascelles

unread,
Oct 26, 2006, 9:59:00 AM10/26/06
to
"Rick Beerendonk" <rick_nospam@_remove_beerendonk.com> wrote in message
news:4540...@newsgroups.borland.com...

> That's why I said: Fire the guy. He not only writes slower and less


> maintainable software, but silly discussions like this also "cost time".

I think Delphi is deceptively easy, because lurking under the surface are
the classic issues of resource protection and leaks, pointers, exceptions,
classes. Delphi code only works right if the programmer keeps to a set of
conventions, which I suspect are not properly explained. Coming from a C++
background, you know what are the issues to learn about, but many Delphi
programmers just don't know the territory.

I see leaky and busted Delphi code on the internet and newsgroups. Also a
lot of C++ Builder code, where C++ guys don't know how to treat Delphi or
C++ classes or exceptions, or the mix of both.

Perhaps RealBasic is more suitable for our overtaxed programmer: .NET
languages have got genuine complexity too.

On the constructive side, can anyone link to good articles, tutorials on
Delphi:

Constructors & Destructors
Class References
Resource protection and exceptions
Exceptions occurring in Destructors
FreeAndNil v.s Free
Virtual Methods

I don't think you can learn this stuff from newsgroups. Also we should be
recommending books.

Roger Lascelles


Peter Morris [Droopy eyes software]

unread,
Oct 26, 2006, 10:08:57 AM10/26/06
to
> Tell him to build a test case that demonstrates a failure if you
> don't use it. ;)

Indeed. Tell him you will pay him £50 for an example of it failing, but if
he cannot then he must stop doing it.


Craig Stuntz [TeamB]

unread,
Oct 26, 2006, 10:09:37 AM10/26/06
to
Bob Dawson wrote:

> That sort of optimization is also quite foolish, of course.

That's putting it mildly.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
How to ask questions the smart way:
http://www.catb.org/~esr/faqs/smart-questions.html

Peter Morris [Droopy eyes software]

unread,
Oct 26, 2006, 10:09:07 AM10/26/06
to
P45


Wayne Niddery [TeamB]

unread,
Oct 26, 2006, 11:29:01 AM10/26/06
to
John Jacobson wrote:
> I have a disagreement with a fellow programmer about how FreeAndNil
> works in Win32 Delphi. He keeps insisting that we need to put "if
> Assigned(x) then" in front of every call to "FreeAndNil(x)". I say
> that we don't need to, because FreeAndNil(x) will do the test for nil
> in the Free code that gets called.

"Use the source".


--
Wayne Niddery - Winwright, Inc (www.winwright.ca)
"Democracy, without the guarantee of liberty, is merely a method of
selecting tyrants." - Alan Nitikman


Wayne Niddery [TeamB]

unread,
Oct 26, 2006, 11:30:40 AM10/26/06
to
John Jacobson wrote:
>
> I DID use the source, and even showed it to this other programmer. He
> STILL insisted that we HAVE to put "if Assigned(x) then" in front of
> our FreeAndNils.

Well, you *know* he's wrong (or certainly should). If he rejects the
evidence of the actual source code, then why is he a programmer and why is
he working there?

--
Wayne Niddery - Winwright, Inc (www.winwright.ca)

SpaceShipOne; GovernmentZero


Wayne Niddery [TeamB]

unread,
Oct 26, 2006, 11:40:49 AM10/26/06
to
Bob Dawson wrote:
> Nevertheless, I suppose (without testing) that it could be
> infinitesimally more efficient than always calling FreeAndNil IF it
> could be shown that x is indeed nil a sufficient percent of the time
> for the specific routine where the assigned() check is being made.
> That sort of optimization is also quite foolish, of course.

But of course this begs the question of whether the call to FreeAndNil is
even justified. In most cases it is *not*. It seems to me that many people
have latched on to FreeAndNil with almost superstitious awe - that it is
*somehow* going to make their code safer and leak proof and thus using it
everywhere instead of only where it is actually called for.

--
Wayne Niddery - Winwright, Inc (www.winwright.ca)

"Bandwagons are like streetcars, there'll be another along in a few
minutes."


Rick Beerendonk

unread,
Oct 26, 2006, 12:00:57 PM10/26/06
to
> But of course this begs the question of whether the call to FreeAndNil is
> even justified. In most cases it is *not*. It seems to me that many people
> have latched on to FreeAndNil with almost superstitious awe - that it is
> *somehow* going to make their code safer and leak proof and thus using it
> everywhere instead of only where it is actually called for.

Same can be said about Free and Destroy in a lot of cases, f.e.

with TButton.Create(nil) do
try
...
finally
Free;
end;

Rick


Bob Dawson

unread,
Oct 26, 2006, 12:01:18 PM10/26/06
to
"Wayne Niddery [TeamB]" wrote

> But of course this begs the question of whether the call to
> FreeAndNil is even justified. In most cases it is *not*.

Agreed--it's quite common to see FreeAndNil being called on a procedure
variable right before it goes out of scope. In general, it seems to me that
the more one follows good OO practice, the less FreeAndNil matters.

bobD


Craig Stuntz [TeamB]

unread,
Oct 26, 2006, 12:18:57 PM10/26/06
to
Rick Beerendonk wrote:

> Same can be said about Free and Destroy in a lot of cases, f.e.

I disagree. Of Destroy, help says:

"Do not call Destroy directly."

This means don't do it, not do it sometimes. Borland/DevCo are
essentially reserving the right to change this in the future. Look at
how Delphi for .NET handles Free for an example.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz

Want to help make Delphi and InterBase better? Use QC!
http://qc.borland.com -- Vote for important issues

Hans-Peter Diettrich

unread,
Oct 26, 2006, 11:52:45 AM10/26/06
to
John Jacobson wrote:

> I DID use the source, and even showed it to this other programmer. He STILL
> insisted that we HAVE to put "if Assigned(x) then" in front of our
> FreeAndNils.

I agree that the Assigned check is very fast, compared to the call of
nested procedures.

Perhaps we should have a NilAndDestroyOnlyIfAssigned() procedure, which
would check for a non-nil reference in the first place, and returns
immediately if there remains nothing to do. Make it a compiler magic, or
an inline procedure, for best performance with minimum writing. (okay,
also rename it into "dia()" ;-)

DoDi

Nathanial Woolls

unread,
Oct 26, 2006, 12:52:13 PM10/26/06
to
"Rick Beerendonk" <rick_nospam@_remove_beerendonk.com> wrote in message
news:4540b3db$1...@newsgroups.borland.com...

>> They even use it inside destructors or at the end of a method[1].
>
> I do that so I don't need to touch that code again when extra code is
> added at the end of the method (f.e.)


Agreed. I've been called an overly defensive coder (never any complaints
from customers), but I *never* use .Free, always FreeAndNil().

Ben604

unread,
Oct 26, 2006, 1:19:00 PM10/26/06
to
obj := TObject.Create;
obj.Free;
FreeAndNil(obj);

The above will cause a Invalid Pointer operation; it does in D5 anyway.

theo

unread,
Oct 26, 2006, 1:16:44 PM10/26/06
to

>
> procedure TObject.Free;
> begin
> if Self <> nil then // <<-- Here goes the testing
> Destroy;
> end;
>
>

Sorry for being extremely stupid, but I didn't ever understand the
meaning of this line:

if Self <> nil then ..

Can somebody explain? How can you call MyObject.free when MyObject is nil?

I'm sure this has been answered 1000 times, but...

Craig Stuntz [TeamB]

unread,
Oct 26, 2006, 1:29:52 PM10/26/06
to
theo wrote:

> Can somebody explain? How can you call MyObject.free when MyObject is
> nil?
>
> I'm sure this has been answered 1000 times, but...

You can call any method on any reference whether or not the reference
is assigned. It's just that if the method accesses any fields of the
instance the call will usually fail.

"Self" is just a hidden argument to a method. It's allowed to be nil,
but it's not generally useful to call a method on a nil reference since
it will die as soon as it accesses a field of the class. Take this
example:

TFoo = class
private
FCount: integer;
public
procedure DoStuff;
end;

procedure TFoo.DoStuff;
{ Think of this as procedure TFoo.DoStuff(var Self: TFoo);}
begin
Beep;
FCount := 1; // this is the same as Self.FCount := 1;
end;

var
Foo: TFoo;
begin
Foo := nil;
Foo.DoStuff;
end;

In this example the Beep works fine, but the assignment to FCount will
be an access violation since the implicit Self argument is nil.
Assigning to FCount means you're dereferencing Self and you can't do
that on a nil pointer.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz

Borland newsgroup denizen Sergio González has a new CD of
Irish music out, and it's good: http://tinyurl.com/7hgfr

Serge Dosyukov (Dragon Soft)

unread,
Oct 26, 2006, 1:31:39 PM10/26/06
to
Is it a problem with the code or style?

And the answer is - not safer at all. So, you could put it, but do not have
to...

Is it slower? Lets see... ;o)
If variable is nil most of the time then you do not call procedure (+1) and
therefore do not perform memory allocation for local variable (+1), 2
assignments (+2) and one more method call (+1) which then checks for the
same "assigned" (+1)
So you have 1 call which could replace 6... ;o)
In this case it is all up to the code implementation.

>I have a disagreement with a fellow programmer about how FreeAndNil works

>in Win32 Delphi. He keeps insisting that we need to put "if Assigned(x)

>then" in front of every call to "FreeAndNil(x)". I say that we don't need
>to, because FreeAndNil(x) will do the test for nil in the Free code that
>gets called.
>

> What think ye? In teh valued opinion of the readers of this fine newsgroup
> is this...
>

> if Assigned(x) then FreeAndNil(x);
>
> ...actually any safer than
>
> FreeAndNil(x);


Bob Dawson

unread,
Oct 26, 2006, 1:30:00 PM10/26/06
to
"Ben604" wrote

> obj := TObject.Create;
> obj.Free;
> FreeAndNil(obj);
>
> The above will cause a Invalid Pointer operation

But so would

obj := TObject.Create;
obj.Free;
if assigned(obj) then
FreeAndNil(obj);

the redundant assigned check adds nothing.

bobD


Jon Shemitz

unread,
Oct 26, 2006, 1:42:24 PM10/26/06
to
theo wrote:

> Sorry for being extremely stupid, but I didn't ever understand the
> meaning of this line:
>
> if Self <> nil then ..
>
> Can somebody explain? How can you call MyObject.free when MyObject is nil?

It's pretty simple, really: TObject.Free is not virtual, so MyObject
is not referenced when you call Free. Rather, the object code simply
reads the current value, and passes it to the method as the Self
parameter.

You can call any instance method with a Nil reference, and everything
will be fine until the method refers to an instance field or calls a
virtual method, at which point you are dereferencing Nil, and you'll
get an exception.

By contrast, when you try to call a virtual method using a Nil
reference, you get an exception at the call point.

--

.NET 2.0 for Delphi Programmers www.midnightbeach.com/.net
Delphi skills make .NET easy to learn Great reviews & good sales.

Andreas Hausladen

unread,
Oct 26, 2006, 1:38:07 PM10/26/06
to
Roger Lascelles wrote:

> Exceptions occurring in Destructors

Add "Exceptions in Constructors"


I too often saw this kind of code:

try
if not Assigned(MyForm) then
MyForm := TMyForm.Create(Application);
Result := MyForm.ShowModal = mrOk;
finally
MyForm.Free;
MyForm := nil;
end;

And the worst is that someone told the other developers that the
constructor call must be between try and finally.

--
Regards,

Andreas Hausladen

Andreas Hausladen

unread,
Oct 26, 2006, 1:44:51 PM10/26/06
to
And now assume that the variable is not nil in most cases...

--
Regards,

Andreas Hausladen

Craig Stuntz [TeamB]

unread,
Oct 26, 2006, 1:46:04 PM10/26/06
to
Craig Stuntz [TeamB] wrote:

> You can call any method on any reference

As Jon points out, I should have said "any non-virtual method" here.

--
Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz

Useful articles about InterBase development:
http://blogs.teamb.com/craigstuntz/category/21.aspx

Wayne Niddery [TeamB]

unread,
Oct 26, 2006, 1:59:54 PM10/26/06
to
Bob Dawson wrote:
>
> Agreed--it's quite common to see FreeAndNil being called on a
> procedure variable right before it goes out of scope. In general, it
> seems to me that the more one follows good OO practice, the less
> FreeAndNil matters.

Where it seems to get used most (that I've seen) is for form variables.
Assign the global variable, and then FreeAndNil it in that form's OnClose
event so that other code can tell whether the form exists or not. Get rid of
the global vars and that "need" goes away. <g> If I need to see if a form
already/still exists, it's no problem to search in Screen.Forms.

--
Wayne Niddery - Winwright, Inc (www.winwright.ca)

"Nurture your mind with great thoughts. To believe in the heroic makes
heroes." — Benjamin Disraeli


theo

unread,
Oct 26, 2006, 2:03:35 PM10/26/06
to
Craig Stuntz [TeamB] schrieb:

> Craig Stuntz [TeamB] wrote:
>
>> You can call any method on any reference
>
> As Jon points out, I should have said "any non-virtual method" here.
>

OK, thanks to you both. I had a misconception about this.

theo

unread,
Oct 26, 2006, 2:18:10 PM10/26/06
to
..But I really didn't know it. ;-)
I thought this would be only possible for class methods.

To sum it up for me and others: This all works:


TTest = class
private

protected

public
class function GetClassVersion:Integer;
function GetVersion:integer;
function GetVersionVirtual:integer; virtual;
published

end;


.....

class function TTest.GetClassVersion: Integer;
begin
Result:=2;
end;

function TTest.GetVersion: integer;
begin
Result:=2;
end;


function TTest.GetVersionVirtual: integer;
begin
Result:=2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var MyTest:TTest;
begin
writeln(TTest.GetClassVersion);
writeln(MyTest.GetVersion);
MyTest:=TTest.Create;
writeln(MyTest.GetVersionVirtual);
MyTest.free;
end;

Ben Taylor

unread,
Oct 26, 2006, 2:15:08 PM10/26/06
to
> But of course this begs the question of whether the call to FreeAndNil is
> even justified. In most cases it is *not*. It seems to me that many people
> have latched on to FreeAndNil with almost superstitious awe - that it is
> *somehow* going to make their code safer and leak proof and thus using it
> everywhere instead of only where it is actually called for.

IMO, FreeAndNil is always justified. It is part of good defensive
programming, like using assertions to check valid input to methods.

for example, freeAndNil gives you extra compile-time checking. eg if you
have a procedure using a const parameter:

procedure doSomething(const aCar:TCar);
begin
showMessage('the car is:'+aCar.color);
aCar.free;
end;

that will compile just fine, yet give you a bug that might be very hard
to track down. (the memory referenced by the tcar instance isn't
cleared, so subsequent access to the now-invalid pointer may actually
succeed, making the situation even worse, and even harder to track down).

compared to this, a more robust implementation, which will give a
compile-time error:

procedure doSomething(const aCar:TCar);
begin
Assert(aCar<>nil);
showMessage('the car is:'+aCar.color);
FreeAndNil(aCar);
end;

This is even more important and useful when refactoring code.

Serge Dosyukov (Dragon Soft)

unread,
Oct 26, 2006, 2:30:26 PM10/26/06
to
Assumption #1: "If variable is nil most of the time then" then probably it
is worth to check

Assumption #2:


> And now assume that the variable is not nil in most cases...

then you do not need to check...

as I said you do not have to check, but you could... and "code is not safer"

it is chicken and egg situation.

"we need to put "if Assigned(x) then" in front of every call to

"FreeAndNil(x)"" (I did not hear "why" answered here) versus "FreeAndNil(x)
is safe by it self" is not opposite statements...
They just represent different view of the code usage - simplistic and
minimalistic.


Jolyon Smith

unread,
Oct 26, 2006, 3:58:46 PM10/26/06
to
In article <45403d57$1...@newsgroups.borland.com>, John Jacobson says...

> I have a disagreement with a fellow programmer about how FreeAndNil works in
> Win32 Delphi.

I have heard it argued that Assigned() being equivalent to <> NIL is a
platform specific implementation detail.

i.e. it is possible that the code, when compiled on some other platform,
may fail if the test for being Assigned did not involve a test for non-
NILness.


> we don't need to,
> because FreeAndNil(x) will do the test for nil in the Free code that gets
> called.

Ah, this was actually point of the delusional fools offering the
platform specific argument.

If you look at TObject.Free, it doesn't use Assigned() to test self, it
checks directly for non-NILness.

So in theory they were right - in the future a call to FreeAndNIL(NIL)
or NIL.Free might fail if on that future platform Assigned'ness was not
related to NIL'ness and for some reason .Free did not perform an
Assignedness test appropraite to that platform.

At least, I think that was what was keeping them awake at nights


So yes:

if Assigned(x) then FreeAndNil(x);

is safer than:

FreeAndNil(x);

The more pertinent question is, is the risk that you are avoiding ever
likely to be an issue?

I don't think it needs a rocket scientist to answer that one!!

--
Jolyon Smith

David Clegg

unread,
Oct 26, 2006, 3:40:48 PM10/26/06
to
Rick Beerendonk wrote:

> I do that so I don't need to touch that code again when extra code is
> added at the end of the method (f.e.)

I do it out of habit and consistency for the times where I'm freeing an
object which may have greater scope.

--
Cheers,
David Clegg
dcl...@gmail.com
http://cc.borland.com/Author.aspx?ID=72299

QualityCentral. The best way to bug Borland about bugs.
http://qc.borland.com

"I think Smithers picked me because of my motivational skills. Everyone
says they have to work a lot harder when I'm around." - Homer Simpson

Ben604

unread,
Oct 26, 2006, 4:38:22 PM10/26/06
to

I stand corrected. Dunno how, but i've run into issues not checking
Assigned before and have been doing it ever since.

Don Strenczewilk

unread,
Oct 26, 2006, 4:20:47 PM10/26/06
to
If you can't beat 'em, join 'em. Concede the point but then tell him that to
be even safer, the code should look like this:

if Assigned(x) then
FreeAndNil(x)
else
x := nil;

Because if by some chance X was not assigned to begin with, then
FreeAndNil() will never get called and therefore X will never get set to
nil.


"John Jacobson" <jake@j[nospam]snewsreader.com> wrote in message
news:45403d57$1...@newsgroups.borland.com...

Lord Crc

unread,
Oct 26, 2006, 5:03:29 PM10/26/06
to
On Wed, 25 Oct 2006 23:45:14 -0500, "John Jacobson"
<jake@j[nospam]snewsreader.com> wrote:

>What think ye? In teh valued opinion of the readers of this fine newsgroup
>is this...

Show him the asm.

- Asbjørn

Nick Hodges (Borland/DTG)

unread,
Oct 26, 2006, 5:07:04 PM10/26/06
to
Don Strenczewilk wrote:

> if Assigned(x) then
> FreeAndNil(x)
> else
> x := nil;

LOL -- that's brilliant!

Of course, an excessively careful programmer would use:

if (Assigned(x)) or (x <> nil) then
begin
FreeAndNil(x)
end else
begin
x := nil;
end;

Because, after all, one can't be sure that Assigned() actually is doint
what it is supposed to be doing. ;-)

--
Nick Hodges
Delphi/C# Product Manager - Borland DTG
http://blogs.borland.com/nickhodges

Bob Dawson

unread,
Oct 26, 2006, 5:54:54 PM10/26/06
to
"David Clegg" wrote

>
> I do it out of habit and consistency for the times where I'm
> freeing an object which may have greater scope.

Don't you know whether it has greater scope?

Sorry, that sounds a lot like always coming to a full stop at a lighted
intersection out of habit and consistency for the times when the light is
red. <g>

bobD


David Clegg

unread,
Oct 26, 2006, 6:44:13 PM10/26/06
to
Bob Dawson wrote:

> Don't you know whether it has greater scope?

Of course I do. It's more about taking a consistent approach in my
code, and being doubly sure that you're not going to be caught out, or
catch out a less experienced co-worker who may be maintaining the same
code base with you.

I also think you have a valid point about FreeAndNil becoming less
relevant in an OO environment, which is a place I've been trying to
gravitate towards more and more over the last few years.

> Sorry, that sounds a lot like always coming to a full stop at a
> lighted intersection out of habit and consistency for the times when
> the light is red. <g>

Heh! I guess it it kinda does boil down to that. :-)

It's threads like this that illustrate exactly why I'm constantly
re-evaluating and challenging my current coding style. Ideas that seem
like no-brainers at the time of adoption often don't make quite as much
sense on reflection, especially as more knowledge and experience is
gained.

QualityCentral. The best way to bug Borland about bugs.
http://qc.borland.com

"Who is Fonzy!?! Don't they teach you anything at school?" - Homer
Simpson

Roger Lascelles

unread,
Oct 26, 2006, 7:35:23 PM10/26/06
to
"Ben Taylor" <to_...@yahoo.com> wrote in message
news:4540fb2d$1...@newsgroups.borland.com...

> IMO, FreeAndNil is always justified. It is part of good defensive
> programming, like using assertions to check valid input to methods.
>
> for example, freeAndNil gives you extra compile-time checking. eg if you
> have a procedure using a const parameter:

> compared to this, a more robust implementation, which will give a


> compile-time error:
>
> procedure doSomething(const aCar:TCar);
> begin
> Assert(aCar<>nil);
> showMessage('the car is:'+aCar.color);
> FreeAndNil(aCar);
> end;
>
> This is even more important and useful when refactoring code.


Don't you mean "run time" checking when assertions are turned on? I don't
think you can test pointers for nil during compilation!

Your use of FreeAndNil is part of your philosophy of programming, rather
than an imperative of the language. I write a lot of code, and I don't get
bad pointer trouble hidden in released executables. Just as C programmers
pass pointers around without testing them for nil all the time, I keep my
pointers in good shape. Its probably to do with my own programming habits.

That is not to detract from your practice. Perhaps it would be useful in
programming teams where others can pass bad pointers. It may also be more
use for larger projects.

Interestingly, the Delphi VCL mostly does not check pointers.

My own approach is to put everything into classes. I avoid pointers, except
inside low level code, which gets debugged once. Whenever possible, I
Create and Free any required objects on the spot, so there are few global
objects lying around. I do all my program initialisation and finalisation
in one place, so no globals are "forgotton". I try to create a class rather
than pass a const or var parameter to a buffer. That does leave a few const
or var parameters, and often I pass a size parameter so memory overrun can
be prevented.

I would like to see more discussion of programming philosophy: not just "do
this", but a look at the pros and cons of each approach. Delphi demands a
lot from the programmer.

Roger Lascelles


Oliver Townshend

unread,
Oct 26, 2006, 7:16:51 PM10/26/06
to
> Because, after all, one can't be sure that Assigned() actually is doint
> what it is supposed to be doing. ;-)

Well to be sure:

try


if (Assigned(x)) or (x <> nil) then
begin

try
FreeAndNil(x)
except
x.Free;
x:=nil;
end;


end else
begin
x := nil;
end;

finally
x:=nil;
end;

Oliver Townshend


Nick Hodges (Borland/DTG)

unread,
Oct 26, 2006, 7:44:22 PM10/26/06
to
Oliver Townshend wrote:

> Well to be sure:

Even better! ;-)

Ben Taylor

unread,
Oct 26, 2006, 8:01:36 PM10/26/06
to
>> procedure doSomething(const aCar:TCar);
>> begin
>> Assert(aCar<>nil);
>> showMessage('the car is:'+aCar.color);
>> FreeAndNil(aCar);
>> end;

> Don't you mean "run time" checking when assertions are turned on? I don't


> think you can test pointers for nil during compilation!

nope. you'll get this compile error on the FreeAndNil call:

[Pascal Error] E2197 Constant object cannot be passed as var parameter

and yes, of course the assert() is runtime, that was just an example of
writing robust code..

> Your use of FreeAndNil is part of your philosophy of programming,
> rather than an imperative of the language.

yup. if you haven't read "code complete" recently, it's well worth it..

> I write a lot of code, and I don't get
> bad pointer trouble hidden in released executables.

thats fine. but as soon as something goes wrong, for whatever reason
(think of all the third party code you run) then i would much rather
debug code that uses assertions, appropriate const and var declarations,
and freeAndNil. it just _eliminates_ entire categories of potential
problems.

it adds up to _knowing_ that your program works correctly, rather than
observing that it seems to.

Bob Dawson

unread,
Oct 26, 2006, 9:11:21 PM10/26/06
to
"Oliver Townshend"
> Well to be sure:

Not there yet---

> try


try
> if (Assigned(x)) or (x <> nil) then
> begin
> try
> FreeAndNil(x)
> except
> x.Free;
> x:=nil;
> end;
> end else
> begin
> x := nil;
> end;

except
continue;
break;
exit;
Application.Terminate;
halt;
ShowMessage('Extreme error. Unplug computer immediately.');
raise;


end;
> finally
> x:=nil;
> end;

http://catb.org/~esr/jargon/html/C/cargo-cult-programming.html

bobD


Hans-Peter Diettrich

unread,
Oct 26, 2006, 7:26:05 PM10/26/06
to
Jolyon Smith wrote:

>>I have a disagreement with a fellow programmer about how FreeAndNil works in
>>Win32 Delphi.
>
>
> I have heard it argued that Assigned() being equivalent to <> NIL is a
> platform specific implementation detail.

Nil can be a platform specific constant value, it only must have an
unique value.

I also don't know of any platform, where Nil/NULL is anything else than
zero.

DoDi

Hans-Peter Diettrich

unread,
Oct 26, 2006, 7:01:24 PM10/26/06
to
theo wrote:

> ...But I really didn't know it. ;-)


> I thought this would be only possible for class methods.

Class methods are designed for working without objects, but other
methods work as well without objects, unless they try to dereference the
Self reference.

>
> To sum it up for me and others: This all works:

[...]


> procedure TForm1.Button1Click(Sender: TObject);
> var MyTest:TTest;
> begin

You should add here:
MyTest := nil;
Otherwise these lines produce random results:

> writeln(MyTest.GetVersionVirtual);
> MyTest.free;

DoDi

Hans-Peter Diettrich

unread,
Oct 26, 2006, 7:19:05 PM10/26/06
to
Ben Taylor wrote:

> procedure doSomething(const aCar:TCar);
> begin
> Assert(aCar<>nil);
> showMessage('the car is:'+aCar.color);
> FreeAndNil(aCar);
> end;
>
> This is even more important and useful when refactoring code.

Even better was the handling of the old Object type, where AFAIR the
destructor invalidated the instance by clearing the VMT pointer - if
virtual methods were present. Since virtual methods always are present
in TObjects, the destructor could automagically clear the VMT pointer in
the destroyed object. Then another check could be added to Assigned():

Result := (obj <> nil) and (obj^ <> nil);

The first check fails if the object reference is nil, the second check
fails if the (assumed) object's VMT pointer is nil.

Note: the VMT pointer should be cleared only after all virtual
destructors are finished, perhaps in the FreeInstance method.

DoDi

Hans-Peter Diettrich

unread,
Oct 26, 2006, 7:36:37 PM10/26/06
to
Don Strenczewilk wrote:

> If you can't beat 'em, join 'em. Concede the point but then tell him that to
> be even safer, the code should look like this:
>
> if Assigned(x) then
> FreeAndNil(x)
> else
> x := nil;

Even better, SCNR:

if Assigned(x) then FreeAndNil(x)
else if not Assigned(x) then x := nil
else ShowMessage('looking for somebody to add more crap!');

This just reminds me on workarounds on a VB compiler bug, addressing bad
handling of booleans. Something similar can be found in many Delphi
programs as well:

if condition <> False then x := True
else x := False;

DoDi

Nick Hodges (Borland/DTG)

unread,
Oct 26, 2006, 8:29:33 PM10/26/06
to
Roger Lascelles wrote:

> I would like to see more discussion of programming philosophy:

One of my philosophies has always been to ruthlessly limit scope. The
more limited the scope of any pointer or reference, the less likely it
is to be accessed incorrectly or at a "bad time".

Pursuant to that, I never call Create without calling Free somewhere
/immediately/. I never defer writing the code freeing a reference.
Thus, I fill out try...finally blocks before adding /any/ code. If I
create something in a constructor, I /immediately/ free it in the
destructor. I use local references whereever and wheneever possible,
and I /never/ use global variables. Ever.

Just my $0.02.

Dan Barclay

unread,
Oct 26, 2006, 9:30:41 PM10/26/06
to
<chuckle> If I had even a hint you guys were serious I'd be running
screaming back to VB (dead or not!) <g>.

Dan

"Nick Hodges (Borland/DTG)" <nick....@borland.com> wrote in message
news:45414856$1...@newsgroups.borland.com...

John Jacobson

unread,
Oct 26, 2006, 9:41:46 PM10/26/06
to
"Nick Hodges (Borland/DTG)" <nick....@borland.com> wrote in message
<454152ed$1...@newsgroups.borland.com>

> One of my philosophies has always been to ruthlessly limit scope. The
> more limited the scope of any pointer or reference, the less likely it
> is to be accessed incorrectly or at a "bad time".
>
> Pursuant to that, I never call Create without calling Free somewhere
> /immediately/. I never defer writing the code freeing a reference.
> Thus, I fill out try...finally blocks before adding /any/ code. If I
> create something in a constructor, I /immediately/ free it in the
> destructor. I use local references whereever and wheneever possible,
> and I /never/ use global variables. Ever.

I wish I was in charge of programming at my current employer instead of the guy
that insists on "if Assigned then" being in front of every FreeAndNil. That is
one thing I would insist on, that things must be freed in the same scope in
which they are created. What better way to prevent problems with lifetime
memory management?

--
***Free Your Mind***

Posted with JSNewsreader Preview 0.9.4.2907


I.P. Nichols

unread,
Oct 26, 2006, 9:41:36 PM10/26/06
to
"Dan Barclay" wrote:
> <chuckle> If I had even a hint you guys were serious I'd be running
> screaming back to VB (dead or not!) <g>.

Those guys make prudent people who wear both belt and suspenders look like
totally irresponsible pantless boobs. <g>

Nick Hodges (Borland/DTG)

unread,
Oct 26, 2006, 10:05:59 PM10/26/06
to
John Jacobson wrote:

> I wish I was in charge of programming at my current employer instead
> of the guy that insists on "if Assigned then" being in front of every
> FreeAndNil.

Yeah, that's, well, not good.

John Jacobson

unread,
Oct 26, 2006, 10:01:28 PM10/26/06
to
Bob Dawson <bda...@idtdna.com> wrote in message
<4540b8b3$1...@newsgroups.borland.com>
> "John Jacobson" wrote
> > other programmer. He STILL insisted that we
> > HAVE to put "if Assigned(x) then" in front of our
> > FreeAndNils.
>
> Then I'm impressed at your tolerance (or your current dosage). The Jake I
> knew did not suffer fools gladly...<g>

Well, maybe I'm mellowing out as I age. I haven't been able to see any
technical harm from his forcing us all to put "if assigned then" in front of
our FreeAndNil calls, so the cost is all economic. I made the mistake of
checking in some code yesterday where I did not put in the "if assigned then"
thing before a FreeAndNil and he sent an email to us all reminding us of this
policy. (BTW, he'll be writing my upcoming review!)

It seems hard to come across Delphi programmers that really know Delphi at an
expert level. I could swear that back when I was in C++, a much higher
percentage of my peers knew the language and tools really well.

Nick Hodges (Borland/DTG)

unread,
Oct 26, 2006, 10:06:26 PM10/26/06
to
Dan Barclay wrote:

> <chuckle> If I had even a hint you guys were serious I'd be running
> screaming back to VB (dead or not!) <g>.

Come on -- defensive programming is safe programming!

John Jacobson

unread,
Oct 26, 2006, 10:23:51 PM10/26/06
to
"Peter Morris [Droopy eyes software]" <pete@NO_droopyeyes_SPAM.com> wrote in
message <4540...@newsgroups.borland.com>
> P45

OK, I'll bite. What does that mean?

John Jacobson

unread,
Oct 26, 2006, 10:23:26 PM10/26/06
to
"Wayne Niddery [TeamB]" <wnid...@chaffaci.on.ca> wrote in message
<4540d49f$1...@newsgroups.borland.com>
> Well, you *know* he's wrong (or certainly should). If he rejects the
> evidence of the actual source code, then why is he a programmer and why is
> he working there?

Perseverance. The guy will code like hell for ungodly number of hours per day
until a bug is fixed. That's how he got the respect of the rest of the company
and why he is in control. Plus he knows the existing code. At least that is
what it looks like to me. I've only been there less than a year.

I've come across this before, where a programmer has gotten himself into a
position of respect not through his knowledge of the language or his brilliance
at programming, but through sheer perseverance. Businesses usually want fixes
and results, and if a programmer is willing to work like hell 14-18 hours a day
to get them, they'll prefer that to a brilliant programmer that will get it all
done in an 8-hour day, but cost a little bit more. (Besides, I get the idea
that this place could not actually hold and attract top-notch programming
talent anyway.)

It will be interesting to see what happens in the future at this place. It was
recently acquired by a much larger firm, a firm that does have top-notch
programming talent and real programming methodologies in place. They recently
sent a bunch of guys down to help out, and they were totally flabbergasted at
the lack of process and the total chaos of the development cycle at this place.
They said "We've never seen anything like it". At least now I know I am not
alone.

John Jacobson

unread,
Oct 26, 2006, 10:28:31 PM10/26/06
to
Robert Giesecke <sp...@spam.spam> wrote in message
<4540...@newsgroups.borland.com>
> Funny thing is, that a lot of Delphians think of FreeAndNil as some magic silver bullet.
> They even use it inside destructors or at the end of a method[1].
> Maybe even cross fingers and jump 3 times in circle to complete the spell, which shall save them from evil memory-leaks. *g*
>
> [1]where there's no way to check a reference afterwards against nil, because there is no reference anymore *g*

Yeah, I would not be surprised if he also believes FreeAndNil is better than
Free for destroying local variables at the end of a method. But then, it
doesn't do any harm either, except in the time it takes to enforce this
department standard.

John Jacobson

unread,
Oct 26, 2006, 10:25:09 PM10/26/06
to
David Dean <ozch...@sneakemail.com> wrote in message
<ozchzhq02-60610...@frylock.local>
> In article <4540...@newsgroups.borland.com>,

> "John Jacobson" <jake@j[nospam]snewsreader.com> wrote:
>
> > I DID use the source, and even showed it to this other programmer. He STILL
> > insisted that we HAVE to put "if Assigned(x) then" in front of our
> > FreeAndNils.
>
> Tell him to build a test case that demonstrates a failure if you
> don't use it. ;)

I've been thinking of offering $500 to anyone that can show an example of it
making a difference.

John Jacobson

unread,
Oct 26, 2006, 10:29:56 PM10/26/06
to
Rick Beerendonk <rick_nospam@_remove_beerendonk.com> wrote in message
<4540...@newsgroups.borland.com>
> Fire the other programmer <g>

The only way to fire one's boss is to leave for another job. I think my wife
would be very cross with me if I changed jobs yet again.

Oliver Townshend

unread,
Oct 26, 2006, 10:39:11 PM10/26/06
to
> I also don't know of any platform, where Nil/NULL is anything else than
> zero.

In SQL Server, Null is not zero. In VB, Nothing is not zero. I vaguely
remember in 286 days that the high order part of nil wasn't necessarily
zero.

Oliver Townshend


John Jacobson

unread,
Oct 26, 2006, 10:41:40 PM10/26/06
to
Bob Dawson <bda...@idtdna.com> wrote in message
<4540dbcc$1...@newsgroups.borland.com>
> Agreed--it's quite common to see FreeAndNil being called on a procedure
> variable right before it goes out of scope. In general, it seems to me that
> the more one follows good OO practice, the less FreeAndNil matters.

Hmmm...Perhaps it would not be unreasonable to expect that well-written code
would never need a single FreeAndNil in the first place.

John Jacobson

unread,
Oct 26, 2006, 10:39:34 PM10/26/06
to
Roger Lascelles <rogerlasAToptusnet.com.au> wrote in message
<4540...@newsgroups.borland.com>
> I think Delphi is deceptively easy, because lurking under the surface are
> the classic issues of resource protection and leaks, pointers, exceptions,
> classes. Delphi code only works right if the programmer keeps to a set of
> conventions, which I suspect are not properly explained. Coming from a C++
> background, you know what are the issues to learn about, but many Delphi
> programmers just don't know the territory.

I think that hits the nail right on the head. Delphi is like a college with an
open admissions policy, with a wide open door for the prospective programmer.
But just because you get in does not mean you get to graduate.

As time goes on lately, I find myself wanting to get away from Delphi in the
workplace. Don't get me wrong, I love Delphi. In my newsreader I chose Delphi
and will continue to keep it in Delphi. But it seems that most Delphi code out
there in the wild is poorly written and poorly maintained, and a lot of the
programmers are ones that you just know would never make it as C++, C# or Java
programmers. Not all, of course. There are some really good Delphi programmers
on this planet. I know because I've met some.

Oliver Townshend

unread,
Oct 26, 2006, 10:39:35 PM10/26/06
to
>> P45
>
> OK, I'll bite. What does that mean?

I think it's a termination form number, i.e. sack him.

Oliver Townshend


David Clegg

unread,
Oct 26, 2006, 10:47:19 PM10/26/06
to
John Jacobson wrote:

> Yeah, I would not be surprised if he also believes FreeAndNil is
> better than Free for destroying local variables at the end of a
> method. But then, it doesn't do any harm either, except in the time
> it takes to enforce this department standard.

Are you using D2006 at work? You could always set up a Live Template to
do the dirty work for you. :-)

OTOH, every development department needs the token Renegade Developer
who doesn't play by the rules. Perhaps you should fill that role, and
continue to use .Free where appropriate. If your development talents
are suitably recognized by the organization, he should hopefully tire
of nagging you about breaking this particular coding standard rather
than insisting on getting you to change.

Then again, if your talents were appreciated for what they are, I'd
expect him to listen to your advise about this matter in the first
place.

--
Cheers,
David Clegg
dcl...@gmail.com
http://cc.borland.com/Author.aspx?ID=72299

QualityCentral. The best way to bug Borland about bugs.
http://qc.borland.com

"If something is too hard to do, then it's not worth doing. You just
stick that guitar in the closet next to your shortwave radio, your
karate outfit and your unicycle and we'll go inside and watch TV." -
Homer Simpson

Jon Shemitz

unread,
Oct 26, 2006, 10:49:11 PM10/26/06
to
John Jacobson wrote:

> a lot of [Delphi]


> programmers are ones that you just know would never make it as C++, C# or Java
> programmers.

I've worked with (and/or inherited the code of) the sort you mean: the
ones who get by on a handful of memorized heuristics; the ones who
tend to write warmed-over procedural code, with everything in the form
object. But surprise! I've seen C++ and C# programmers like this, too.

--

.NET 2.0 for Delphi Programmers www.midnightbeach.com/.net
Delphi skills make .NET easy to learn Great reviews & good sales.

John Jacobson

unread,
Oct 26, 2006, 10:45:13 PM10/26/06
to
Robert Giesecke <sp...@spam.spam> wrote in message
<4540...@newsgroups.borland.com>
> John Jacobson wrote:
> >
> > I DID use the source, and even showed it to this other programmer. He STILL insisted that we HAVE to put "if Assigned(x)
> > then" in front of our FreeAndNils.
>
> You mentioned that before... I think in your "WTF" thread, right?

No, that was another programmer and another construct. That was this:

Dataset.Open;
while not Dataset.eof do
try
...do stuff...
finally
Dataset.Next;
end;

Jim Rowell

unread,
Oct 26, 2006, 10:53:32 PM10/26/06
to
John Jacobson wrote:

>
> I wish I was in charge of programming at my current employer instead
> of the guy that insists on "if Assigned then" being in front of every
> FreeAndNil. That is one thing I would insist on, that things must be
> freed in the same scope in which they are created. What better way to
> prevent problems with lifetime memory management?

Press F1 for him.

According to Borland, Assigned() is the equivalent of "<> nil".
Since Free already does that check, he's simply doing it twice.

Far as I know, the following 2 items are exactly the same.

if assigned(aObj) then
freeandnil(aObj);

if aObj <> nil then
if aObj <> nil then
begin
aObj.free;
aObj := nil;
end;

One thing I don't get is why FreeAndNil is written the way it is.
From the SysUtils unit:

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

Why didn't they just do:

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


John Jacobson

unread,
Oct 26, 2006, 10:57:11 PM10/26/06
to
"Peter Morris [Droopy eyes software]" <pete@NO_droopyeyes_SPAM.com> wrote in
message <4540c17b$1...@newsgroups.borland.com>
>
> Indeed. Tell him you will pay him £50 for an example of it failing, but if
> he cannot then he must stop doing it.

You mean telling me to do it.

John Jacobson

unread,
Oct 26, 2006, 11:00:22 PM10/26/06
to
Ben604 <bend...@yahoo.co.uk> wrote in message
<1161883140.8...@i42g2000cwa.googlegroups.com>
> obj := TObject.Create;
> obj.Free;
> FreeAndNil(obj);
>
> The above will cause a Invalid Pointer operation; it does in D5 anyway.

So here's a question:

What is the difference there that causes an Invalid Pointer operation instead
of an Access Violation?

Jim Rowell

unread,
Oct 26, 2006, 11:03:16 PM10/26/06
to
John Jacobson wrote:
> Bob Dawson <bda...@idtdna.com> wrote in message
> <4540dbcc$1...@newsgroups.borland.com>
>> Agreed--it's quite common to see FreeAndNil being called on a
>> procedure variable right before it goes out of scope. In general, it
>> seems to me that the more one follows good OO practice, the less
>> FreeAndNil matters.
>
> Hmmm...Perhaps it would not be unreasonable to expect that
> well-written code would never need a single FreeAndNil in the first
> place.

It seems reasonable to me for some things especially forms where you want
the option of being able to let a form live but be hidden and other times
you want to destroy the same form. The code that "shows" the form has to be
prepared to create it or just show it. Always setting the form var to nil
after freeing means a simple check for nil determines whether to create or
just show.

Is there a better way of doing that?


Jon Shemitz

unread,
Oct 26, 2006, 11:06:33 PM10/26/06
to
Jim Rowell wrote:

> One thing I don't get is why FreeAndNil is written the way it is.

> procedure FreeAndNil(var Obj);


> var
> Temp: TObject;
> begin
> Temp := TObject(Obj);
> Pointer(Obj) := nil;
> Temp.Free;
> end;
>
> Why didn't they just do:
>
> procedure FreeAndNil(var Obj);
> begin
> TObject(Obj).free;
> Pointer(Obj) := nil;
> end;

The SysUtils code will set the reference to Nil even if Free raises an
exception - without the expense of a try/finally block.

John Jacobson

unread,
Oct 26, 2006, 11:14:06 PM10/26/06
to
"Serge Dosyukov (Dragon Soft)" <pooh996.gmail.com> wrote in message
<4540...@newsgroups.borland.com>
> "we need to put "if Assigned(x) then" in front of every call to
> "FreeAndNil(x)"" (I did not hear "why" answered here)

The explanation I was offered was that if x had never been assigned that
FreeAndNil(x) would "cause problems". When I asked what they meant, the two of
them then elaborated by saying that it would be messing up memory that only
causes AV's later, not there. Or something like that.

Jim Rowell

unread,
Oct 26, 2006, 11:08:02 PM10/26/06
to
Jon Shemitz wrote:
> Jim Rowell wrote:
>
>> One thing I don't get is why FreeAndNil is written the way it is.
>
>> procedure FreeAndNil(var Obj);
>> var
>> Temp: TObject;
>> begin
>> Temp := TObject(Obj);
>> Pointer(Obj) := nil;
>> Temp.Free;
>> end;
>>
>> Why didn't they just do:
>>
>> procedure FreeAndNil(var Obj);
>> begin
>> TObject(Obj).free;
>> Pointer(Obj) := nil;
>> end;
>
> The SysUtils code will set the reference to Nil even if Free raises an
> exception - without the expense of a try/finally block.

Of course. Glad I asked. Thanks.


John Jacobson

unread,
Oct 26, 2006, 11:17:48 PM10/26/06
to
Ben Taylor <to_...@yahoo.com> wrote in message
<4540fb2d$1...@newsgroups.borland.com>
> compared to this, a more robust implementation, which will give a
> compile-time error:
>
> procedure doSomething(const aCar:TCar);
> begin
> Assert(aCar<>nil);
> showMessage('the car is:'+aCar.color);
> FreeAndNil(aCar);
> end;
>
> This is even more important and useful when refactoring code.

True, but isn't an even better design one in which aCar is freed in the same
scope in which it was created?

John Jacobson

unread,
Oct 26, 2006, 11:33:44 PM10/26/06
to
David Clegg <dcl...@gmail.com> wrote in message
<xn0esyzt...@newsgroups.borland.com>

> Are you using D2006 at work?

I wish. We are using D6 at that place. My suggestions that we think about
upgrading were dead in the water, DOA, stillborn.

> You could always set up a Live Template to
> do the dirty work for you. :-)

Well, it's the principle of the thing.

>
> OTOH, every development department needs the token Renegade Developer
> who doesn't play by the rules. Perhaps you should fill that role, and
> continue to use .Free where appropriate. If your development talents
> are suitably recognized by the organization, he should hopefully tire
> of nagging you about breaking this particular coding standard rather
> than insisting on getting you to change.

I thought that would happen after the first one or two times, but it is slowly
dawning on me just how much of a plebe I actually am.

>
> Then again, if your talents were appreciated for what they are, I'd
> expect him to listen to your advise about this matter in the first
> place.

Yeah, that particular subtlety has definitely not escaped my notice. But the
wife doesn't want me changing jobs anymore.

John Jacobson

unread,
Oct 26, 2006, 11:44:28 PM10/26/06
to
Jon Shemitz <j...@midnightbeach.com> wrote in message
<454177B9...@midnightbeach.com>

>
> The SysUtils code will set the reference to Nil even if Free raises an
> exception - without the expense of a try/finally block.

Wow, you're good! No wonder you wrote a book.

Ben Taylor

unread,
Oct 26, 2006, 11:40:37 PM10/26/06
to
>> procedure doSomething(const aCar:TCar);
>> begin
>> Assert(aCar<>nil);
>> showMessage('the car is:'+aCar.color);
>> FreeAndNil(aCar);
>> end;
>>
>> This is even more important and useful when refactoring code.
>
> True, but isn't an even better design one in which aCar is freed in the same
> scope in which it was created?

design isn't the point of this example. this was purely to illustrate
that FreeAndNil can give compile-time checking, where .Free doesn't.

anyway there are many cases where it's innappropriate/impossible to free
in the same scope. threaded producer/consumer queues for example.

John Jacobson

unread,
Oct 26, 2006, 11:39:51 PM10/26/06
to
Jon Shemitz <j...@midnightbeach.com> wrote in message
<454173A7...@midnightbeach.com>

> John Jacobson wrote:
>
> > a lot of [Delphi]
> > programmers are ones that you just know would never make it as C++, C# or Java
> > programmers.
>
> I've worked with (and/or inherited the code of) the sort you mean: the
> ones who get by on a handful of memorized heuristics; the ones who
> tend to write warmed-over procedural code, with everything in the form
> object.

That reminds me of yet another gem that I've seen at the same place. A new
coding standard that says that every method must be a function that returns
true/false by catching all exceptions and setting a global LastError variable.
No more allowing exceptions to affect program flow at all. I REALLY bristled at
that one. I happen to think object oriented exception handling is a good thing.

John Jacobson

unread,
Oct 26, 2006, 11:54:54 PM10/26/06
to
Ben Taylor <to_...@yahoo.com> wrote in message
<45417fe5$1...@newsgroups.borland.com>

> anyway there are many cases where it's innappropriate/impossible to free
> in the same scope. threaded producer/consumer queues for example.

Indeed, I've written many a threadsafe producer/consumer that destroyed objects
in a different scope/area than that in which they were created.

It is interesting when you think about it, but using reference-counted
objects/interfaces like .NET does, completely gets rid of the need to think
about scope relative to optimal object lifetime management.

Jon Shemitz

unread,
Oct 27, 2006, 12:04:50 AM10/27/06
to
John Jacobson wrote:

> > The SysUtils code will set the reference to Nil even if Free raises an
> > exception - without the expense of a try/finally block.
>
> Wow, you're good!

Yeah, I know ;-) but, actually, I think Ray Lischner pointed that one
out to me while I was writing my Kylix book.

John Jacobson

unread,
Oct 27, 2006, 12:15:43 AM10/27/06
to
Jon Shemitz <j...@midnightbeach.com> wrote in message
<45418562...@midnightbeach.com>

> I think Ray Lischner pointed that one
> out to me while I was writing my Kylix book.

Any idea what Ray is doing these days? His Delphi in a Nutshell book is sitting
on my shelf at work, and his C++ in a Nutshell book is sitting on my shelf here
at home. I talked to Ray a bit when BorCon was right across the street from
Disneyland in Anaheim. He was slowly walking back from the Tuesday night
special event, and I mean slowly. Chatted for a bit as he walked. I guess he
has Rheumatoid Arthritis or something like that. Very peaceful, calm demeanor,
almost Zen.

BTW, I got the C++ book for free from either Brion Webster or Robert Love, who
either had won two from the last-day Borland Money raffle or just did not want
or need it for some reason. I also remember that one of those two rapscallions
brazenly grabbed an airborne T-shirt obviously destined for the other.

Jon Shemitz

unread,
Oct 27, 2006, 12:24:54 AM10/27/06
to
John Jacobson wrote:

> Any idea what Ray is doing these days?

You could write him - afaik, he's still got the same Tempest Software
addr that he used to post from.

Last I heard from him was on an authors' list: He's in Maryland, these
days, and he's got the arthritis enough under control that he's
writing again. All C++.

John Jacobson

unread,
Oct 27, 2006, 12:32:33 AM10/27/06
to
Jon Shemitz <j...@midnightbeach.com> wrote in message
<45418A16...@midnightbeach.com>

> Last I heard from him was on an authors' list: He's in Maryland, these
> days, and he's got the arthritis enough under control that he's
> writing again. All C++.

I was talking to someone today from our parent company and was surprised
(pleasantly) to find that C/C++ is still being heavily used for a lot of rather
mission critical stuff. C++ is the language that never dies. It will probably
still be used 30 years from now.

David Clegg

unread,
Oct 27, 2006, 2:17:48 AM10/27/06
to
John Jacobson wrote:

> That reminds me of yet another gem that I've seen at the same place.
> A new coding standard that says that every method must be a function
> that returns true/false by catching all exceptions and setting a
> global LastError variable. No more allowing exceptions to affect
> program flow at all. I REALLY bristled at that one. I happen to think
> object oriented exception handling is a good thing.


Heh! I had an argument with one of our developers about that topic
recently too. He hated the notion of using exceptions to notify the
caller of a problem, or ensuring that code execution doesn't carry on
down a certain path if an invalid condition is encountered. Instead he
preferred the 'every method returns an error code' route, putting the
onus on the caller to bail if something isn't quite right.

I couldn't convince him that exceptions cannot be ignored, but return
values of functions can, so throwing exceptions is the only way to
guarantee that your exception will be noticed and the code will not
continue down an execution path if it shouldn't (normal caveats about
people not abusing SEH apply here, of course).

OTOH, he also doesn't get OO at all, and isn't great at writing
encapsulated code. So the concept that the consumer of the class may
not be the author, or that it may be used in multiple places, probably
didn't occur to him either.

--

QualityCentral. The best way to bug Borland about bugs.
http://qc.borland.com

"No, no, no, Lisa. If adults don't like their jobs, they don't go on
strike. They just go in every day and do it really half-assed. That's
the American Way." - Homer Simpson

David Clegg

unread,
Oct 27, 2006, 2:24:00 AM10/27/06
to
John Jacobson wrote:

> It is interesting when you think about it, but using
> reference-counted objects/interfaces like .NET does, completely gets
> rid of the need to think about scope relative to optimal object
> lifetime management.

Yeah, but it can lull the developer into a false sense of security
where a forgotten object reference can still cause a 'memory leak'.

QualityCentral. The best way to bug Borland about bugs.
http://qc.borland.com

"I think Smithers picked me because of my motivational skills. Everyone
says they have to work a lot harder when I'm around." - Homer Simpson

Eric Grange

unread,
Oct 27, 2006, 2:56:59 AM10/27/06
to
> The SysUtils code will set the reference to Nil even if Free raises an
> exception - without the expense of a try/finally block.

In practice however, it means when the debugger stops on an exception, it means
that the reference to the object was being freed isn't up for inspection
anymore, which isn't desirable.

Also, it means that FreeAndNil breaks its implicit naming contract, since it is
actually performing a NilAndFree, which isn't desirable either.

Eric

Eric Grange

unread,
Oct 27, 2006, 2:49:03 AM10/27/06
to
> Not there yet---

You forgot to protect those two lines

x.Free;
x:=nil;

with a try finally/try except too in case the .Free fails!

Eric

Eric Grange

unread,
Oct 27, 2006, 2:44:37 AM10/27/06
to
> [...] completely gets rid of the need to think

> about scope relative to optimal object lifetime management.

Not caring about scope (whatever the reason or purpose) is the mother of all
spaghetti code. In many ways it's not very different from using try...except to
gobble up exceptions: it "neatly" hides problems, but doesn't solve them.

Eric

Roger Lascelles

unread,
Oct 27, 2006, 3:46:24 AM10/27/06
to
"Ben Taylor" <to_...@yahoo.com> wrote in message
news:45414c74$1...@newsgroups.borland.com...

> nope. you'll get this compile error on the FreeAndNil call:
>
> [Pascal Error] E2197 Constant object cannot be passed as var parameter
>

To simplify you code:

procedure doSomething(const aCar:TCar);
begin

aCar.free;
end;

procedure doSomething(const aCar:TCar);
begin

FreeAndNil(aCar);
end;


Now I see what your example is about. The compiler can check that class
reference passed to FreeAndNil is const. But calling the objects own Free
member can't be checked.

I never free a parameter in a called procedure. I never pass classes as
const parameters, because they are already references (pointers) and the
extra indirection is of no value. I'm not going to get any value from this
example.


> it adds up to _knowing_ that your program works correctly, rather than
> observing that it seems to.

You never _know_ that your program works correctly. You only know that 1)
the compiler accepted it and 2) you didn't observe an error or assertion
during testing. We all live with this uncertainty. We take steps to
minimise the risk.

Roger Lascelles


Rick Beerendonk

unread,
Oct 27, 2006, 4:01:30 AM10/27/06
to
> I wish I was in charge of programming at my current employer instead of
> the guy
> that insists on "if Assigned then" being in front of every FreeAndNil.
> That is
> one thing I would insist on, that things must be freed in the same scope
> in

> which they are created. What better way to prevent problems with lifetime
> memory management?

If you can't change, let him read this ng? Hmmm... might be a bad idea.

You could create a AssignedFreeAndNil procedure. At first that would contain
the two lines you boss wants. But later, when nobody looks into the
procedure anymore, you change it into a copy of the FreeAndNil procedure.
That's what I would do.

Rick


Dennis Landi

unread,
Oct 27, 2006, 4:35:42 AM10/27/06
to

"Nick Hodges (Borland/DTG)" <nick....@borland.com> wrote in message
news:454152ed$1...@newsgroups.borland.com...
> Roger Lascelles wrote:
>
>> I would like to see more discussion of programming philosophy:
>
> One of my philosophies has always been to ruthlessly limit scope. The
> more limited the scope of any pointer or reference, the less likely it
> is to be accessed incorrectly or at a "bad time".
>
> Pursuant to that, I never call Create without calling Free somewhere
> /immediately/. I never defer writing the code freeing a reference.
> Thus, I fill out try...finally blocks before adding /any/ code. If I
> create something in a constructor, I /immediately/ free it in the
> destructor. I use local references whereever and wheneever possible,
> and I /never/ use global variables. Ever.
>
> Just my $0.02.
>

"Me too". For serious (contract) work, I pretty much write everything as a
series of components. It doesn't really take any extra effort, because so
much time is save by the component design itself. I don't really see myself
as an "application" programmer in this respect.

I wonder what that will feel like when I move to C++. Hmm.

-d


Anders Isaksson

unread,
Oct 27, 2006, 4:44:28 AM10/27/06
to
John Jacobson wrote:
>
> Hmmm...Perhaps it would not be unreasonable to expect that
> well-written code would never need a single FreeAndNil in the first
> place.

I don't know about 'well-written', but I don't have a single
FreeAndNil() in my code. I have never seen the need for it.

--
Anders Isaksson, Sweden
BlockCAD: http://web.telia.com/~u16122508/proglego.htm
Gallery: http://web.telia.com/~u16122508/gallery/index.htm

Claude Rieth

unread,
Oct 27, 2006, 5:51:18 AM10/27/06
to
Nick Hodges (Borland/DTG) wrote:
> Roger Lascelles wrote:
>
>
>>I would like to see more discussion of programming philosophy:
>
>
> One of my philosophies has always been to ruthlessly limit scope. The
> more limited the scope of any pointer or reference, the less likely it
> is to be accessed incorrectly or at a "bad time".
>
> Pursuant to that, I never call Create without calling Free somewhere
> /immediately/. I never defer writing the code freeing a reference.
> Thus, I fill out try...finally blocks before adding /any/ code. If I
> create something in a constructor, I /immediately/ free it in the
> destructor. I use local references whereever and wheneever possible,
> and I /never/ use global variables. Ever.
>
> Just my $0.02.
>

Same for me.

Except for global variables. I group them in a global object, stored in
a separate unit, usually called global.pas, something like :

TGlobal = class
public
CompanyName: string;
BusinessYear: integer;
BankAccountNumbers: TStringList;
constructor Create;
Destructor Destroy;
end;

var
glo: TGLobal;


The TStringlist will be created/freed in the Constructor/Destructor.

TGlobal is instantieted/freed in initialisation/finalisation section of
unit.

What's so good about this:

Only *ONE* real global variable, typing glo. somewhere in your code with
autocompletion shows available variables like CompanyName or
BusinessYear etc. and all your global variables are declared in one unit.

Works great for me.

Regards,
Claude

It is loading more messages.
0 new messages