I spotted that they fixed that a while ago - I remember having to fix the issue myself many years ago so was quite pleased to see that it was now taken care of in TInterfaceObject as a matter of course. For some reason I never noticed the omission of the same facility in the destructor. And yes, it's a [potentially] big problem.
I need to think about this tho... setting a fake ref count during execution of the constructor is safe enough as you know precisely when construction is done and to restore the ref count back to zero. Setting a fake ref count during destruction strikes me as more problematic and makes me nervous, but I can't quite put my finger on why. It might be nothing. That doesn't mean it can't be fixed, only that the solution put in place for construction might not work for destruction and it wasn't felt necessary to do any extra work for a more comprehensive solution. Certainly in the case of my code where I fixed this I had specific "constructing" / "destructing" state markers (it wasn't a general purpose interfacedobject class but a base class in a far richer framework that happened to also implement its own version of IUnknown) - I know I didn't rely on side effects of a faked ref count. From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On Behalf Of Todd Sent: Wednesday, 24 November 2010 16:55 To: NZ Borland Developers Group - Delphi List Subject: [DUG] How's this for inconsistent The Delphi developer who implemented TInterfacedObject obviously considered the case when an interface reference is grabbed during construction...... // Set an implicit refcount so that refcounting // during construction won't destroy the object. class function TInterfacedObject.NewInstance: TObject; begin Result := inherited NewInstance; TInterfacedObject(Result).FRefCount := 1; end; procedure TInterfacedObject.AfterConstruction; begin // Release the constructor's implicit refcount InterlockedDecrement(FRefCount); end; but didn't consider applying the same logic during destruction. So grabing an interface reference during destruction causes all hell to break loose, as the _Release method tries to free the object again and again recursively. procedure TInterfacedObject.BeforeDestruction; begin if RefCount <> 0 then Error(reInvalidPtr); end; function TInterfacedObject._Release: Integer; begin Result := InterlockedDecrement(FRefCount); if Result = 0 then Destroy; end; Todd.
_______________________________________________ NZ Borland Developers Group - Delphi mailing list Post: delphi@delphi.org.nz Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe