Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Delphi compiler can't see I'm trying to free an interface?

I've done a small mistake while coding this week-end.
In the following code, I'm creating an object and cast it to an interface. Later, I'm trying to free it with FreeAndNil();

type
  IMyIntf = interface
     [...]
  end;

  TMyClass = class(TInterfacedObject, IMyIntf)
     [...]
  end;

var
  Myintf : IMyIntf;
begin
  Myintf := TMyClass.Create;
  [...] // Some process
  FreeAndNil(Myintf); // CRASH !!!
end;

Of course, the program crash at this line. I totally understand the issue, but what I don't understand is why the compiler doesn't warn me about it ? There is no dynamic things behind, it's just that I'm trying to free an interface !!! Why don't it write me an error / warning ?

Is there any real explanation behind or is it just a compiler limitation ?

like image 967
TridenT Avatar asked Oct 31 '11 22:10

TridenT


1 Answers

As you know, the correct way to do this is to write Myintf := nil, or just to let it go out of scope. The question you ask is why the compiler accepts FreeAndNil(Myintf) and does not complain at compile time.

The declaration of FreeAndNil is

procedure FreeAndNil(var Obj);

This is an untyped parameter. Consequently it will accept anything. You passed an interface, but you could have passed an integer, a string and so on.

Why did the designers choose an untyped parameter? Well, they needed to use a var parameter since the whole purpose of FreeAndNil is to free the object and set the object reference to nil. That can't be done by a method of the target object and so a var parameter of a standalone function is needed.

You might imagine that you could write

procedure FreeAndNil(var Obj: TObject);

since all objects are descended from TObject. But this does not do the job. The reason being that the object you pass to a var parameters must be exactly the type of that parameter. If FreeAndNil was declared this way you would have to cast to TObject every time you called it.

So, the designers decided that the best solution to the design problem, the least bad choice, is to use the untyped var parameter.

like image 78
David Heffernan Avatar answered Nov 15 '22 07:11

David Heffernan