[fpc-pascal] reference-counted function results not initialized to nil

Karoly Balogh (Charlie/SGR) charlie at scenergy.dfmk.hu
Sun Jun 26 14:27:20 CEST 2016


Hi,

On Sun, 26 Jun 2016, Jürgen Hestermann wrote:

Ok, scrap what I wrote before... :|

You are right about the managed types initialization. But then the
documentation needs to be corrected there too. But actually, result is not
a local var, but in fact a "special" parameter of the function. My bad.
See below.

> The only exception (at least since FPC 3) is the function result
> which is totally unexpected.
> Why such an exception?

There's no exception. At least not specifically for Result. It is simply
variable passed by reference from the caller side, therefore it's not
initialized inside the function. And this is A., consistent with other var
parameters B., apparently also how Delphi does it. Actually, since managed
types are always passed by reference, this is not really a surprise, nor
an exception.

Actually, I tend to agree that it is very misleading. Also, you are also
right that this is new behavior in current compiler. At least 2.6.2 (I
don't have 2.6.4 at hand) decreased the reference to the result parameter
before handing it to the called function, which no longer seems to happen.
(I'm looking at the generated code.)

I have vague memories of a lengthy thread related to this, which changed
the refcounting behavior of reference passed managed types/strings, maybe
we're observing a sideeffect of this? (I think it was related to what
happens if the same reference counted variable is passed to multiple var
types and/or results, maybe also out parameters were involved. It's a
pretty grey area, which is not really documented anywhere...)

To show the problem, what happens with:

var
  a: ansistring;
a:=some_function(a);

If the caller code destroys the result variable (by decreasing the
reference count, because it's a result, so lets initialize it) it won't be
valid by the time you pass it as parameter "a', because only the function
itself will increase its reference then... Also, depending on the order of
parameter passing, you might get different results on different CPU
platforms... (Fix me?) Of course the function itself could also initialize
the result, but we're back to square one with that, if result and one of
the parameters are the same, weird things might happen.

I wish someone with real clue of calling conventions would comment. Jonas
maybe?

Charlie


More information about the fpc-pascal mailing list