[fpc-devel] (ref types / circles) Re: Defer keyword

Sven Barth pascaldragon at googlemail.com
Mon May 10 23:09:56 CEST 2021


Am 09.05.2021 um 17:14 schrieb Ryan Joseph via fpc-devel:
>
>> On May 9, 2021, at 3:40 AM, Sven Barth <pascaldragon at googlemail.com> wrote:
>>
>> === code begin ===
>>
>> {$mode objfpc}
>>
>> type
>>    TTest = class
>>    protected
>>      procedure DoSomething;
>>    end;
>>
>>    TTestSub = class refcounted(TTest)
>>    public
>>      procedure Test;
>>    end;
>>
>> procedure TTest.DoSomething;
>> begin
>>    // maybe this functions stores the reference
>>    SomeFuncThatTakesAObject(Self);
>> end;
>>
>> procedure TTest.Test;
>> begin
>>    DoSomething;
>> end;
>>
>> === code end ===
> I see, the reference counting is broken because you move up into a non-ref counted class. Yeah that's something programers simply should not do or be prevented from doing. I don't see this particular case being a problem however because your ref counted object is going to be in the base of a hierarchy, probably enforced even. The only reason for opt-in ARC is so we don't pollute TObject but it still doesn't mean that  you should be adding this in the middle of class trees.

But that won't stop users from introducing reference counted classes 
somewhere down in the tree. Enabling reference counting by type is 
essentially introducing a new class hierarchy and that makes it useless 
for interacting with the existing RTL/FCL/LCL.

> Here is the bigger problem:
>
> var
>    list: TObjectList;
>
> procedure HandleObject(obj: TObject);
> begin
>     // the list now stores the class but it's lost ref-counting because it was cast to TObject
>     list.Add(obj);
> end;
>
> var
>    obj: TTestSub;
> begin
>    HandleObject(obj);
> end;
>
> or
>
> var
>    obj: TObject;
> begin
>    // we  lost ref counting now!
>    obj := TTestSub.Create;
>    HandleObject(obj);
> end;
>
> Once you cast away from your managed class type things fall apart. Records aid this by not allowing casting but you could enforce some kinds of checks for managed classes if you wanted to. Doesn't seem like a deal breaker to me if you add new type rules for passing/assigning.

That is exactly *the same* problem, not a "bigger" one. It doesn't 
matter if the instance is passed to a function right away or through 
using Self in a parent class, the result is the same: the reference 
count is no longer accurate.

And *that* is why I'm in favor of an approach that is external to the 
class. It's much clearer then that this is not something inherent to the 
class and thus users won't expect this to be handled transparently (and 
this is also why I'm against a keyword like Michael suggested, it only 
wakes expectations that we won't and can't fullfill).

Regards,
Sven


More information about the fpc-devel mailing list