[fpc-devel] Managed Types, Undefined Bhaviour
Jonas Maebe
jonas at freepascal.org
Fri Jun 29 22:33:44 CEST 2018
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
More information about the fpc-devel
mailing list