[fpc-devel] Question on constref

Michael Van Canneyt michael at freepascal.org
Thu Feb 2 11:00:55 CET 2023



On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:

> On 02.02.2023 10:22, Michael Van Canneyt via fpc-devel wrote:
>> On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
>>> On 02.02.2023 10:15, Michael Van Canneyt via fpc-devel wrote:
>>>> On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
>>>>> I myself cannot think of any real use case of constref other than hacks 
>>>>> like the FreeAndNil in recent Delphi versions:
>>>>> 
>>>>> procedure FreeAndNil(const [ref] Obj: TObject);
>>>>> 
>>>>> that needs the ref because it changes it to nil (so is not really a 
>>>>> const - it used to be an untyped var). As a result FreeAndNil allows you 
>>>>> to happily pass read-only properties to it that are then nilled.
>>>> 
>>>> Which is a clear violation of the concept of Const... :/
>>> 
>>> Exactly.
>> 
>> Probably an ill-advised "fix" to the problem that FreeAndNil accepted an 
>> untyped var
>> and you could basically pass anything.
>
> Yes. Solving one problem by creating a different one. The best would be if 
> the FreeAndNil declaration alternated between constref and untyped var 
> between builds. In that case you would be able to hunt both the issues :)
>
> Seriously, having a [loose] modifier would be much more useful, IMO:
>
> FreeAndNil(var [loose] Obj: TObject);
>
> That would allow you to pass any TObject descendant.

It would solve this problem, but introduces another problem, since it would be
usable anywhere:

Procedure DoSomething(var [loose] Obj: TObject);

var
   a : TSomeObject;

begin
   a:=TSomeobject.Create;
   DoSomething(a);
end;

after DoSomething, A may contain a class that is not a TSomeObject at all,
leading to more problems.

In userspace, the best seems

Function FreeAndNil<T :TObject>(Obj : T) : T;

begin
   Obj.Free;
   Result:=Nil;
end;

With automatic type inference for generics, this allows you to do

A:=FreeAndNil(A);

Which is quite acceptable IMO. If you could add inline to the generic
definition the overhead would be minimal.

As it is, FreeAndNil() seems like another candidate for a compiler intrinsic ;-)

Michael.


More information about the fpc-devel mailing list