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
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel