<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div> </div>
<div>Hi Jonas,</div>
<div> </div>
<div>(Sorry for TOFU, I'm doing this from a web interface.) </div>
<div> </div>
<div>First, how you implement things cannot dictate the semantics of the language. It is the other way around. Similarly and by analogy, Spectre/Meltdown for sure are bugs that need fixing and you don't treat them as features because they help performance. Second, even if you do DoSomething(3,A) followed by DoSomething(3,B) I excpect A and B to be distinct. In no case there was anything passed on from A to B. Finally, semantically, it needs to be an out parameter as you cannot pass in values from a language point of view and I don't care about why Delphi behaves correct (in this case), or what the optimizer can or cannot do. This is about the spec/semantics of the language and not about an artifact of how the compiler is implemented. The latter would exactly be the C approach that let's you shoot yourself numerous times in the foot without even knowing - for the sake of potential optimizations.</div>
<div> </div>
<div>TBH, I didn't know this issue existed in Delphi and I've done my share of Delphi over time. I still maintain that for managed types the compiler is responsible for some minimal initialization (like it's done for records etc, no?). If I want high performance, then I'm not using managed types, obviously. If I want to have comfort, I will use them and expect reasonable behaviour. And for most of the time I'm not using FPC or Delphi for the reasons of performance anyways, but to get things done quickly and efficiently (hence all the refcounting managed types...) and without having to deal with unexpected side-effects due to "optimization". With its small community, optimization in FPC/Delphi will never catch up to languages like C/C++ or Fortran in any case. </div>
<div> </div>
<div>Thanks,</div>
<div> Willibald</div>
<div> </div>
<div>
<div name="quote" style="margin:10px 5px 5px 10px; padding: 10px 0 10px 10px; border-left:2px solid #C3D9E5; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">
<div style="margin:0 0 10px 0;"><b>Gesendet:</b> Donnerstag, 28. Juni 2018 um 20:06 Uhr<br/>
<b>Von:</b> "Jonas Maebe" <jonas@freepascal.org><br/>
<b>An:</b> fpc-devel@lists.freepascal.org<br/>
<b>Betreff:</b> Re: [fpc-devel] Managed Types, Undefined Bhaviour</div>
<div name="quoted-content">On 28/06/18 18:45, Willibald Krenn wrote:<br/>
><br/>
> type Vector = array of integer;<br/>
> function DoSomething (len: longint): Vector; begin<br/>
> SetLength (result,len); // whatever<br/>
> end;<br/>
><br/>
> var A,B: Vector;<br/>
> begin<br/>
> A := DoSomething(3);<br/>
> // changing A here will influence B below,<br/>
> // which seems ok to some as<br/>
> // "managed types are not initialized when<br/>
> // calling DoSomething and this is documented<br/>
> // - so anything goes and stop whining".<br/>
> B := DoSomething(3);<br/>
> end.<br/>
><br/>
> I strongly believe that the behaviour as currently implemented is wrong<br/>
> and here is why.<br/>
> (1) When assigning "result" to A, refcount of result needs to go down<br/>
> and, hence, the local var needs to be freed/invalidated. (Result goes<br/>
> out of scope.)<br/>
<br/>
For performance reasons, managed function results are implemented as<br/>
call-by-reference parameters. This is also the case in Delphi:<br/>
<a href="http://docwiki.embarcadero.com/RADStudio/Berlin/en/Program_Control#Handling_Function_Results" target="_blank">http://docwiki.embarcadero.com/RADStudio/Berlin/en/Program_Control#Handling_Function_Results</a><br/>
<br/>
Therefore the function result's scope is the caller of the function, not<br/>
the function itself.<br/>
<br/>
> (3) The behaviour is incompatible to Delphi (tested 10.2.3 vs. Lazarus<br/>
> 1.8.0).<br/>
<br/>
It is compatible with Delphi. See e.g.<br/>
<a href="https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg43050.html" target="_blank">https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg43050.html</a><br/>
<br/>
> Delphi shows the expected behaviour of treating A and B as distinct.<br/>
<br/>
That's because your example gets optimized better by Delphi than by FPC:<br/>
Delphi directly passes A resp. B as the function result "var" parameter<br/>
to the function calls in your example, while FPC passes a/the same<br/>
temporary variable to them and then assigns this temprary variable to A/B.<br/>
<br/>
If you have more complex code where the Delphi compiler cannot be<br/>
certain that the variable to which you assign the function result isn't<br/>
used inside the function as well, it will behave in a similar way (as<br/>
discussed in the StackOverflow posts linked from the message above).<br/>
<br/>
<br/>
Jonas<br/>
_______________________________________________<br/>
fpc-devel maillist - fpc-devel@lists.freepascal.org<br/>
<a href="http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel" target="_blank">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a></div>
</div>
</div></div></body></html>