[fpc-devel] Managed Types, Undefined Bhaviour

Jonas Maebe jonas at freepascal.org
Thu Jun 28 20:06:23 CEST 2018

On 28/06/18 18:45, Willibald Krenn wrote:
> type  Vector = array of integer;
> function DoSomething (len: longint): Vector; begin
>    SetLength (result,len); // whatever
> end;
> var  A,B: Vector;
> begin
>    A := DoSomething(3);
>    // changing A here will influence B below,
>    // which seems ok to some as
>    // "managed types are not initialized when
>    // calling DoSomething and this is documented
>    // - so anything goes and stop whining".
>    B := DoSomething(3);
> end.
> I strongly believe that the behaviour as currently implemented is wrong 
> and here is why.
> (1) When assigning "result" to A, refcount of result needs to go down 
> and, hence, the local var needs to be freed/invalidated. (Result goes 
> out of scope.)

For performance reasons, managed function results are implemented as 
call-by-reference parameters. This is also the case in Delphi: 

Therefore the function result's scope is the caller of the function, not 
the function itself.

> (3) The behaviour is incompatible to Delphi (tested 10.2.3 vs. Lazarus 
> 1.8.0).

It is compatible with Delphi. See e.g. 

> Delphi shows the expected behaviour of treating A and B as distinct.

That's because your example gets optimized better by Delphi than by FPC: 
Delphi directly passes A resp. B as the function result "var" parameter 
to the function calls in your example, while FPC passes a/the same 
temporary variable to them and then assigns this temprary variable to A/B.

If you have more complex code where the Delphi compiler cannot be 
certain that the variable to which you assign the function result isn't 
used inside the function as well, it will behave in a similar way (as 
discussed in the StackOverflow posts linked from the message above).


More information about the fpc-devel mailing list