I recently came across (again) the Delphi compiler code-gen bug when passing an interface as const leaks a reference.
This happens if your method is declared to pass an
This happens if your method is declared to pass an interface variable as const, e.g.:
procedure Frob(const Grob: IGrobber);
That's not quite right. In order for there to be a leak, you need for there to be nothing in the code that ever takes a reference to the newly created object. So if you write:
Frob(grob);
There there's no problem because the interface grob
already has at least one reference.
The problem arises when you write:
Frob(TGrobberImplementer.Create);
In that scenario nothing takes a reference to the interface and so it is leaked. Well, it will be leaked so long as nothing in the implementation of Frob
takes a reference to it.
Have I done a bad thing?
Well, that depends. I don't think anything particularly bad will come of what you have done. There is a downside in terms of performance because all of your functions that accept interface parameters will now have to add and release references, using implicit try/finally blocks. Only you can judge whether that matters.
The more significant issue relates to code that is outside of your control. You give
procedure OnDocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant);
as an example. There's no issue there because you never call that method. It's an event handler that you implement. The framework calls it, and it passes an interface that is already referenced.
The real problem comes from methods declared in the RTL or any other third party code that you call. If you are calling the methods, and if they use const
interface arguments then you can fall into the trap.
It's easy enough to work around, albeit tiresome.
grob := TGrobberImplementer.Create;
Frob(grob);
My reasoning to deal with the issue goes like this:
const
interface parameters at least some of the time.const
.