Yet Another Word about FreeAndNil
The FreeAndNil discussion never stops. I decided to add my twopence. How about this:
{.$DEFINE FREEANDNIL}
{$IFDEF FREEANDNIL}
procedure FreeObj(var Obj); inline;
begin
FreeAndNil(Obj);
end;
{$ELSE}
procedure FreeObj(Obj: TObject); inline;
begin
Obj.Free;
end;
{$ENDIF}
With FreeObj procedure you can have both “defensive coding” for debugging and clean production code. It is also clear that FreeAndNil is used just for debugging, so future maintainers will not be mislead and distracted by FreeAndNil usage. Since FreeObj is inlined, it does not also have an influence on the executable code size.
Advertisement
You seem to forget that Free and FreeAndNil have different purposes. Code that tries to hide this is no better than code that uses FreeAndNil everywhere. Differentiating between both is exactly what makes good code.
Exactly. The suggested code above would introduce new “only in release mode” bugs, where FreeObj is called harmlessly in debug mode, but in a way that can cause access violations, crashes and other weirdness in runtime. Hardly what I’d call “clean”. Use FreeAndNil(x) where x might already be nil, and save yourself from the access violation. Use FreeAndNil(x) when you want to avoid having to set x := nil after calling if Assigned(x) then x.Free. Use it when it’s safer and better, and don’t when you don’t have to.
W
If this code were really meant for using FreeAndNil() only for debugging, then shouldn’t it use {$IFDEF _DEBUG} instead of {$IFDEF FreeAndNil}?
Some folks would like to keep ‘FreeAndNil’ in production code. Using ‘FreeObj’ explicitly declares that ‘FreeAndNil’ is used for defensive coding only, and if the code contains no errors it does not matter what is used – ‘Free’ or ‘FreeAndNil’.
Using FreeAndNil is not “defensive coding”. If items are only freed when they are not publicly accessible nor needed anymore, there is nothing to defend against. It is paranoid coding.
Using FreeAndNil is just the same than using GOTO on structured code, it breaks it and is not elegant!