[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:
http://docwiki.embarcadero.com/RADStudio/Berlin/en/Program_Control#Handling_Function_Results
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.
https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg43050.html
> 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).
Jonas
More information about the fpc-devel
mailing list