which "managed" result types require extra work?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

which "managed" result types require extra work?

David Emerson
Okay, making a new thread here, to ask one question:

Which types do we need to initialize to null/nil/zero/'' when they are a
function result?

- dynamic arrays

- ansistring
- unicodestring
- string, with {$H+} (but not string[length])

- records containing any of them

- anything else???

I understand COM-style interfaces are also managed types, do they also
need a manual initialization to nil if a function result?

And, I'll ask again because it never got answered:

Is there any compiler switch or option that we can use to do this
automatically? (which won't be disabled with any optimization level)

...

As a note... practically, this is a huge pain; if I have a record type
that I use extensively, and then I add an ansistring or dynamic array
field to that record type, then I'm going to have to look all over my
code for functions returning that result type, and fix the initialization.

Anyway...

Thanks,
David


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

Dimitrios Chr. Ioannidis-2
On 27/6/2016 3:55 πμ, David Emerson wrote:

> Okay, making a new thread here, to ask one question:
>
> Which types do we need to initialize to null/nil/zero/'' when they are
> a function result?
>
> - dynamic arrays
>
> - ansistring
> - unicodestring
> - string, with {$H+} (but not string[length])
>
> - records containing any of them
>
> - anything else???
>
> I understand COM-style interfaces are also managed types, do they also
> need a manual initialization to nil if a function result?

As a rule of thumb i follow barry kelly answer, and then specific for
fpc if / when the need arise, ask here ....


PS:
http://stackoverflow.com/questions/861045/which-variables-are-initialized-when-in-delphi/861178#861178

regards,

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

David Emerson
In reply to this post by David Emerson
Addendum - what about a return value which is a class that implements an
interface?



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

Jonas Maebe-2
In reply to this post by David Emerson
David Emerson wrote:

> Which types do we need to initialize to null/nil/zero/'' when they are a
> function result?

Results of all types (managed or not) need to be set to "empty" if you
want them to return an "empty" result.

> I understand COM-style interfaces are also managed types, do they also
> need a manual initialization to nil if a function result?

Even if they didn't/don't, that would only be an implementation detail.
As a rule of thumb, function results do not contain a predictable value
on function entry.

> Is there any compiler switch or option that we can use to do this
> automatically? (which won't be disabled with any optimization level)

No.

> As a note... practically, this is a huge pain; if I have a record type
> that I use extensively, and then I add an ansistring or dynamic array
> field to that record type, then I'm going to have to look all over my
> code for functions returning that result type, and fix the initialization.

If a record type does not contain an ansistring or a dynamic array, you
also have to initialise results of functions returning such a type to
get them to return a "empty" value. If you add a field that is not a
managed type, you will also have to go through your code to add
initialisation code for that field everywhere.

So I'm not sure how this is different from any other type.


Jonas

PS: there is an intrinsic that can help you in this process: the
"default" intrinsic. Default(TSomeType) returns an instance of a
particular type completely initialised to "empty" (0 for ordinal and
floating point types, empty for strings, nil for pointers etc). You can
assign this to e.g. your function results on entry, so that even when
you add fields (of any type) to records you don't have to add additional
initialisation code.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

David Emerson
On 06/26/2016 10:51 PM, Jonas Maebe wrote:
 > PS: there is an intrinsic that can help you in this process: the
 > "default" intrinsic. Default(TSomeType) returns an instance of a
 > particular type completely initialised to "empty" (0 for ordinal and
 > floating point types, empty for strings, nil for pointers etc). You
 > can assign this to e.g. your function results on entry, so that even
 > when you add fields (of any type) to records you don't have to add
 > additional initialisation code.

This is very helpful, thank you.

I also tried Initialize, but this does not seem to work effectively in
all cases; Default seems to work with everything I've thrown at it.

> If a record type does not contain an ansistring or a dynamic array, you
> also have to initialise results of functions returning such a type to
> get them to return a "empty" value. If you add a field that is not a
> managed type, you will also have to go through your code to add
> initialisation code for that field everywhere.
>
> So I'm not sure how this is different from any other type.

The source of my confusion -- and I suspect that of many others -- is
that I always assumed a function result was treated like a local
variable within the function, rather than a parameter to the function.

Since managed types are automatically initialized when they are local
variables, I assumed a function result was the same.

Unfortunately, the documentation does not make this sufficiently clear
in describing managed types. I guess I should file a documentation bug.

Thanks,
David


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

Jürgen Hestermann
Am 2016-06-28 um 01:13 schrieb David Emerson:
 > The source of my confusion -- and I suspect that of many others -- is that I always assumed a function result was treated like a local variable within the function, rather than a parameter to the function.
 > Since managed types are automatically initialized when they are local variables, I assumed a function result was the same.
 > Unfortunately, the documentation does not make this sufficiently clear in describing managed types. I guess I should file a documentation bug.

Exactly my opinion too.
Especially, because it behaved differently with Free Pascal versions prior to 3!

And it does not behave like a function parameter, it behaves like a *var* parameter.
All other types of parameters behave differently!
And while a var parameter can *only* be assigned to a variable (so that it is clear
that an existing variable is used) a function result can also be used in an
expression which makes it silently mutate into a global variable! What a mess!

And for local variables I can easily set a default value in the declaration but not for the function result.
I have to remind me not to forget this in the code.

It is so logical that managed types are managed (therefore the wording!).
That a function result can inherit old values from prior calls is just the same as for
local constants of TP.  But in TP it was at least documented and it was predictable.
Now everybody ostracizes such behaviour but instead intruduces the same
for function results.

I used this behaviour of managed types over many years.
Now we all (most of us) had to find out the change the hard way (by debugging).
Many may not even have found this yet because their functions with managed type results are used seldomly.
That's quite ignorant C style (where you also have nothing to rely on but need to check every compiler (version)).
So yes, "modern" Pascal is no longer the "old" Pascal, but has it become better? Meanwhile I doubt this.

And what about perfomance? In most of the cases I am now initializing
what is already initialized. Very strange.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: which "managed" result types require extra work?

Michael Van Canneyt


On Tue, 28 Jun 2016, Jürgen Hestermann wrote:

> Am 2016-06-28 um 01:13 schrieb David Emerson:
>> The source of my confusion -- and I suspect that of many others -- is that
> I always assumed a function result was treated like a local variable within
> the function, rather than a parameter to the function.
>> Since managed types are automatically initialized when they are local
> variables, I assumed a function result was the same.
>> Unfortunately, the documentation does not make this sufficiently clear in
> describing managed types. I guess I should file a documentation bug.
>
> Exactly my opinion too.
> Especially, because it behaved differently with Free Pascal versions prior to
> 3!
>
> And it does not behave like a function parameter, it behaves like a *var*
> parameter.
> All other types of parameters behave differently!
> And while a var parameter can *only* be assigned to a variable (so that it is
> clear
> that an existing variable is used) a function result can also be used in an
> expression which makes it silently mutate into a global variable! What a
> mess!
>
> And for local variables I can easily set a default value in the declaration
> but not for the function result.
> I have to remind me not to forget this in the code.
This has been so since day 1 in Pascal.

Any behaviour other than that was entirely coincidental.

Michae.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal