Search code examples
delphifreeprocedurenull

Why FreeAndNil implementation doing Nil before Free?


If you will look at the code of FreeAndNil procedure you will see:

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

What is the reason they assigning Nil to an object reference and only after this destroying it? Why not vice-versa?


Solution

  • I can think of two reasons for doing it this way round, neither of which seems at all compelling.

    Reason 1: to guarantee that the reference is set to nil in case an exception is raised

    The implementation achieves this. If the destructor raises, then the reference is still set to nil. Another way to do so would be with a finally block:

    try
      TObject(Obj).Free;
    finally
      TObject(Obj) := nil;
    end;
    

    The downside of this is performance. Particularly on x86 a try/finally is a little expensive. In such a fundamental routine it is prudent to avoid this expense.

    Why do I find the desire to nil at all costs not to be compelling? Well, as soon as destructor start failing you may as well give up. You can no longer reason clearly about your program's state. You cannot tell what failed and what state your program is in. It is my view that the correct course of action in the face of a destructor that raises is to terminate the process.

    Reason 2: to ensure that other threads can detect that the object is being destroyed

    Again this is achieved but it is of no practical use. Yes you can test whether the reference is assigned or not. But then what? The other thread cannot call methods on the object without synchronization. All you could do is learn whether or not the object is alive. And if that is so, why would it matter if this status changed before or after the destructor runs?

    So whilst I present this as a possible reason I cannot believe that anyone in Embarcadero was really swayed by this argument.