Posts

Showing posts with the label Parameters

Hello Old New Leaky Friend

Image
Developers that extensively use interfaces in Delphi probably know about a long-standing issue with the compiler, where interface parameters declared as const or [ref] will cause a memory leak if a reference-counted object instance is constructed directly at the call site. Illustration: Sandra Prasnikar        Specifically, the following code would create a leak: procedure LeakTest(const Intf: IInterface); begin end; procedure Run; begin LeakTest(TInterfacedObject.Create); end; begin ReportMemoryLeaksOnShutdown := True; Run; end. The problem arises because the compiler does not create a hidden interface reference that would properly initialize the reference counting mechanism and keep the object instance alive during the call. In other words, such an object would never be assigned to a strong interface reference. Because const and [ref] parameters don't trigger reference counting, if there is no other code within the called routine, the obj...

Pass the Dog, Get the Cat

This story begins with the FreeAndNil procedure, why its signature could not have a typed var parameter, why we can only pass variables declared as TObject to such procedures, and why the compiler refuses to compile if we try passing any other variable type even if it is a descendant of TObject . procedure FreeAndNil(var Obj); So why does the compiler enforce this behavior? If we take a look at the FreeAndNil implementation and imagine it with a typed var parameter, it may seem that the compiler is throwing us curve balls for nothing. There is nothing we do inside that procedure that would warrant a compiler error for passing TObject descendant types: assigning variable to another TObject variable - pass assigning nil to original variable - pass freeing original object instance stored in temporary variable - pass procedure FreeAndNil(var Obj: TObject); var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; var Obj: TSomeObject...