On 29/06/18 22:02, Stefan Glienke wrote:
If I am not mistaken (this is from my observarion and might not be 100% accurate) usually the rule in Delphi (possibly similar in FPC) when it allows to directly pass the LHS as hidden result parameter is when it is a local variable.

FPC does it when it knows for certain the target cannot be read or modified by the called function. Even for local variables, this is not always the case, e.g. if the local variable's address may have been taken at some point: by the address parameter, or simply because it was passed as var- or out-parameter (the called function could then take the address of that parameter and store it elsewhere). I.e., it is based on alias analysis.

With whole-program analysis, it could also be done with global variables, or in cases the compiler could prove that the function that received a (local) variable as var/out-parameter did not take its address and store it in a location that survived the lifetime of the called function.

That's what I meant when I said this proposal defines language behaviour based on the limitations of a compiler's implementation of alias analysis. Nobody can be 100% accurate about this because this can change from one compiler version to another, unless you limit yourself to the very first implementation your original compiler had. Any improvement could break working code.

Now with the dynamic array we have the case that since the content of the temp variable was being copied it then when being reused has a ref count of 1 causing SetLength to just realloc the memory and possibly keep any existing content of the array copying it then on to the LHS of a second statement as shown in the code example earlier.

I fully agree it is counter-intuitive. But I disagree that only solving the issue in specific cases (which aren't even documented anywhere) is a solution. Either you go all the way, or you don't do it.

Having the programmer keep manual track of when a managed type might need extra initialisation does not make sense. After all, when you change your code, behaviour could change because suddenly a local variable might have a value at a point where previously it didn't. Having to follow all code paths to see whether somewhere you call a function that does not initialise its function result so you can add an extra nil-initialisation of that managed local variable is the opposite of robust code.

IMO there is a potential cause for a code defect that is not obvious - you might go the way of the principle of least surprises and try to address it

The principle of least surprises would be to always use temps and to always initialise them before passing them as function result. I think many more people would expect this rather than "it is usually initialised to nil". It would of course result in complaints that FPC performs extra initialisations of managed variables compared to Delphi.

or argue it away for whatever reasons.

That is no way to discuss.


Jonas
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to