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 ?
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 acceptsFreeAndNil(Myintf)and does not complain at compile time.The declaration of
FreeAndNilisThis 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
varparameter since the whole purpose ofFreeAndNilis to free the object and set the object reference tonil. That can’t be done by a method of the target object and so avarparameter of a standalone function is needed.You might imagine that you could write
since all objects are descended from
TObject. But this does not do the job. The reason being that the object you pass to avarparameters must be exactly the type of that parameter. IfFreeAndNilwas declared this way you would have to cast toTObjectevery 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.