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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With