Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-09

Why does nested function get corrupted?

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hairy Pixels

Curious more than anything, if is nested captures state in a record and passes it as an hidden self param, why does returning the variable and calling from outside the calling stack frame corrupt the data? It seems like it technically should be there.

==================

type
  TProc = procedure is nested;
function TestNested: TProc;
var
  data: integer;
begin
  data := 100;
  result := procedure
  begin
    writeln(data);
  end;
end;
var
  proc: TProc;
begin
  proc := TestNested;
  proc();
end.

Regards,
Ryan Joseph

Sven Barth
to Hairy Pixels

Hairy Pixels via fpc-pascal schrieb am
Fr., 9. Sep. 2022, 00:52:

Show quoted text 5 lines
Curious more than anything, if is nested captures state in a record and passes it as an hidden self param, why does returning the variable and calling from outside the calling stack frame corrupt the data? It seems like it technically should be there.

How about you simply report such corruptions as bugs? I can always close them as "not a bug" or duplicate if necessary.

Regards,
Sven

Hairy Pixels
to Sven Barth
On Sep 9, 2022, at 4:48 PM, Sven Barth wrote: How about you simply report such corruptions as bugs? I can always close them as "not a bug" or duplicate if necessary.

Well I thought the data may have been saved on the stack and thus lost when the function exits. What is the expected behavior for passing these outside of the calling scope?

Regards,
Ryan Joseph

Sven Barth
to Hairy Pixels

Hairy Pixels schrieb am Sa., 10. Sep. 2022, 03:21:

Show quoted text 13 lines
> On Sep 9, 2022, at 4:48 PM, Sven Barth wrote: > > How about you simply report such corruptions as bugs? I can always close them as "not a bug" or duplicate if necessary. > Well I thought the data may have been saved on the stack and thus lost when the function exits. What is the expected behavior for passing these outside of the calling scope?

Looking at your example again - I'm only on my phone currently - it's indeed your fault because the state passed to a nested function variable does *not* survive the stack frame it belongs to. That's where function references shine, because there the state *does* survive.

Regards,
Sven

Ondrej Pokorny
to Sven Barth
Sven Barth wrote 20 lines
Hairy Pixels schrieb am Sa., 10. Sep. 2022, 03:21: > On Sep 9, 2022, at 4:48 PM, Sven Barth wrote: > > How about you simply report such corruptions as bugs? I can always close them as "not a bug" or duplicate if necessary. > Well I thought the data may have been saved on the stack and thus lost when the function exits. What is the expected behavior for passing these outside of the calling scope? Looking at your example again - I'm only on my phone currently - it's indeed your fault because the state passed to a nested function variable does *not* survive the stack frame it belongs to. That's where function references shine, because there the state *does* survive.

Shouldn't this assignment be forbidden?

type
   TProc = procedure is nested;
function TestNested: TProc;
begin
   result := procedure // why is this possible?
   begin
     writeln(data);
   end;

It is not a nested function but an anonymous one.

Ondrej

Sven Barth
to Ondrej Pokorny

Ondrej Pokorny via fpc-pascal schrieb am
So., 11. Sep. 2022, 12:18:

Show quoted text 37 lines
Am 11.09.2022 um 11:26 schrieb Sven Barth via fpc-pascal: Hairy Pixels schrieb am Sa., 10. Sep. 2022, 03:21: > > > > On Sep 9, 2022, at 4:48 PM, Sven Barth > wrote: > > > > How about you simply report such corruptions as bugs? I can always > close them as "not a bug" or duplicate if necessary. > > > > Well I thought the data may have been saved on the stack and thus lost > when the function exits. What is the expected behavior for passing these > outside of the calling scope? > Looking at your example again - I'm only on my phone currently - it's indeed your fault because the state passed to a nested function variable does *not* survive the stack frame it belongs to. That's where function references shine, because there the state *does* survive. Shouldn't this assignment be forbidden? type TProc = procedure is nested; function TestNested: TProc; begin result := procedure // why is this possible? begin writeln(data); end; It is not a nested function but an anonymous one.

And? An anonymous function is assignment compatible to multiple left sides depending on what it captures. See my announcement mail.

Regards,
Sven

Ondrej Pokorny
to Sven Barth
Sven Barth wrote 19 lines
Ondrej Pokorny via fpc-pascal schrieb am So., 11. Sep. 2022, 12:18: Shouldn't this assignment be forbidden? type TProc = procedure is nested; function TestNested: TProc; begin result := procedure // why is this possible? begin writeln(data); end; It is not a nested function but an anonymous one. And? An anonymous function is assignment compatible to multiple left sides depending on what it captures. See my announcement mail.

Thank you Sven - I missed this info in your email.

Ondrej

Sven Barth
to Ondrej Pokorny

Ondrej Pokorny via fpc-pascal schrieb am
So., 11. Sep. 2022, 15:29:

Show quoted text 24 lines
Am 11.09.2022 um 14:22 schrieb Sven Barth via fpc-pascal: Ondrej Pokorny via fpc-pascal schrieb am So., 11. Sep. 2022, 12:18: > Shouldn't this assignment be forbidden? > > type > TProc = procedure is nested; > function TestNested: TProc; > begin > result := procedure // why is this possible? > begin > writeln(data); > end; > > It is not a nested function but an anonymous one. > > And? An anonymous function is assignment compatible to multiple left sides depending on what it captures. See my announcement mail. Thank you Sven - I missed this info in your email.

It's an extension I had done compared to Delphi so that anonymous functions are also usable without function references which are a bit more heavy weight after all.

Regards,
Sven