<div dir="ltr">> The compiler turns such functions into procedures with an implicit
var-parameter<br><div>> and the *caller* passes the location where the function
result should go via that<br>> parameter.<br><br></div><div>Okay, thanks, that clarifies, now I understand how a variable in the caller's scope can be affected while making assignments to Result in the callee's scope BEFORE callee has finished executing. <br>
<br>Another way of stating this is; Result is a local variable of a function, initialized to nil and passed by value to the caller upon completion ONLY if Result not a reference to a dynamic type, otherwise it's an implicit var argument with scope beyond that of the function.<br>
<br>Is that correct? If so, it would seem to be a bit of semantic trap for the unwary :-)<br><br>> Such optimizations only occur in safe situations (e.g., not when assigning to a<br>> global variable...<br><br></div>
<div>Does the compiler consider ANY non-local variable to be global?<br><br>For example, fields of an object?<br></div><div><br>> So you are probably writing in two threads to whatever you are assigning the<br>> result of that function to.<br>
<br></div><div>Yep, makes sense, we will look carefully to see if that's what we're doing.<br><br>The functions concerned are actually methods of the TBlockSocket class of the synapse library. We use an instance of this class in two threads; one sending, the other receiving. <br>
<br>These threads have full shared memory protection in our own code but having a look at the TBlockSocket implementation I can see at least one suspect; FLastErrorDesc.<br><br>This field is changed by methods that send and receive on the socket which means it's assigned values in the context of two different threads (given our usage). Indeed it suggests TBlockSocket is not thread safe as currently coded. Looks like a smoking gun to me.<br>
<br>Thanks one and all for all your helpful feedback!<br><br></div><div>Bruce.<br></div><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, May 9, 2013 at 10:55 PM, Jonas Maebe <span dir="ltr"><<a href="mailto:jonas.maebe@elis.ugent.be" target="_blank">jonas.maebe@elis.ugent.be</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
On 09 May 2013, at 14:39, Bruce Tulloch wrote:<br>
<br>
> Thanks José, I can see that might cause a problem given bar passes result<br>
> by reference to foo without initializing result first. My question to Jonas<br>
> or others more knowledgeable than me about what the compiler does, is<br>
> whether result (in your example and my own case) is guaranteed to be<br>
> initialized to nil when it first appears in scope (i.e. before it's been<br>
> assigned any value in our code).<br>
<br>
</div>Every instance of an automated type, whether it was explicitly declared or implicitly created as a temp, initially gets the value "nil".<br>
<br>
However, as Michael and Ludo explained, the "result" variable of a function returning an ansistring/unicodestring is not created inside that function itself. The compiler turns such functions into procedures with an implicit var-parameter and the *caller* passes the location where the function result should go via that parameter. This location can be a temporary location, but the compiler can also optimize this by directly passing the location of the variable to which you assign the result of that function call. Such optimizations only occur in safe situations (e.g., not when assigning to a global variable, because otherwise assigning something to the function result would immediately change the value of that global variable too), but as Ludo explains this means that you are looking in the wrong place for the data race.<br>
<br>
So you are probably writing in two threads to whatever you are assigning the result of that function to.<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
Jonas_______________________________________________<br>
</font></span><div class="HOEnZb"><div class="h5">fpc-pascal maillist - <a href="mailto:fpc-pascal@lists.freepascal.org">fpc-pascal@lists.freepascal.org</a><br>
<a href="http://lists.freepascal.org/mailman/listinfo/fpc-pascal" target="_blank">http://lists.freepascal.org/mailman/listinfo/fpc-pascal</a><br>
</div></div></blockquote></div><br></div>