Recent

Author Topic: Does not go out of function  (Read 804 times)

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 390
Does not go out of function
« on: February 14, 2026, 01:06:23 pm »
This is not all code obviously, but something like that ....
Any clue ?


Quote
Proc()
  fuction NestedFunction()
  begin
    //...
    if ..... recursive call of NestedFunction  repeatedly

    result := something;//does not go out, instead goes to to top of NestedFunction, not allways ...
  end;

 
begin
  res := NestedFunction ();
end;

« Last Edit: February 14, 2026, 01:08:34 pm by BubikolRamios »
lazarus 3.2-fpc-3.2.2-win32/win64

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 390
Re: Does not go out of function
« Reply #1 on: February 14, 2026, 01:24:18 pm »
namely figured

Code: Pascal  [Select][+][-]
  1.  
  2. function
  3. for
  4.  
  5. recursive call of function while for next is not over jet
  6.  
  7. next
  8.  
  9.  
lazarus 3.2-fpc-3.2.2-win32/win64

WooBean

  • Sr. Member
  • ****
  • Posts: 303
Re: Does not go out of function
« Reply #2 on: February 14, 2026, 01:28:08 pm »
Try to ask the forum in a more disciplined way - this will be probably enough to get the answer yourself before posting the question.

An excerpt from a compilable code is the best way.
« Last Edit: February 14, 2026, 01:49:29 pm by WooBean »
Platforms: Win7/64, Linux Mint 22.1 Xia

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 390
Re: Does not go out of function
« Reply #3 on: February 14, 2026, 02:21:03 pm »
Try to ask the forum in a more disciplined way - this will be probably enough to get the answer yourself before posting the question.

An excerpt from a compilable code is the best way.

Said namely, compilable code not possible.
lazarus 3.2-fpc-3.2.2-win32/win64

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12208
  • Debugger - SynEdit - and more
    • wiki
Re: Does not go out of function
« Reply #4 on: February 14, 2026, 02:21:06 pm »
Is this about stepping (F7 / F8) in the debugger?

There is an issues in the compiler, that writes incorrect "debug info". The compiler tells the debugger that the code of the final "end" line is (partly) in the "begin" line.

So when you step onto the "end" line, the debugger will do what the compiler said => it steps up to the begin line.

That can happen up to 3 or 4 times (going end, begin, end, begin, end and then step out.

There are similar issues with "try expect/finally" that lead to extra steps onto the "begin" line.




Also, you should compile with "optimization OFF"  -O- (level 0).

It will still do the end/begin stepping, but it will allow you to step onto lines like

Code: Pascal  [Select][+][-]
  1.   if foo then
  2.     exit;
  3.   for a := 0 to c do
  4.      if bar then
  5.         break;

exit, break and similar are often optimized away with -O1 or higher. And then you canst step onto them, and you can't set breakpoints.

With -O- they usually work in the debugger.
« Last Edit: February 14, 2026, 02:24:06 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12208
  • Debugger - SynEdit - and more
    • wiki
Re: Does not go out of function
« Reply #5 on: February 14, 2026, 02:28:55 pm »
In case of a recursive function. When and if the last line is the recursive call...
Code: Pascal  [Select][+][-]
  1. procedure foo;
  2. begin
  3.  ...
  4.   if xyz then
  5.     foo; // last line of the procedure
  6. end;

If you compile that with -O2 (IIRC O2 and above), then you may get optimization, where the nested call is inlined.

That call to FOO may not be a call, instead the function may be inlined (several times).


Mind that O2 gives terrible debugging, your variables will most of the time show wrong values....

BubikolRamios

  • Sr. Member
  • ****
  • Posts: 390
Re: Does not go out of function
« Reply #6 on: February 14, 2026, 03:16:26 pm »
In case of a recursive function. When and if the last line is the recursive call...
Code: Pascal  [Select][+][-]
  1. procedure foo;
  2. begin
  3.  ...
  4.   if xyz then
  5.     foo; // last line of the procedure
  6. end;

If you compile that with -O2 (IIRC O2 and above), then you may get optimization, where the nested call is inlined.

That call to FOO may not be a call, instead the function may be inlined (several times).


Mind that O2 gives terrible debugging, your variables will most of the time show wrong values....


Here, I managed to reproduce.

Put breakpoint onto "result := localInt;", ok when 10, lands there.
Do not remove break point, press F9, observe localInt value, goes backwards 9,8,7,.....
While if you put additional breakpoints anywhere, looks like everything that happens is on "breaked line" and nowhere else.
Obviously there is no - anywhere.
And it does not go out as said at OP, when one would expect.
The 0 instead of 10 comes out even if there are no breakpoins.

How to fix that ?

Code: Pascal  [Select][+][-]
  1. procedure TForm2.Button22Click(Sender: TObject);
  2.   function f(j: integer): integer;
  3.   var
  4.     localInt : integer = 0;
  5.     i: integer;
  6.   begin
  7.       localInt := j +1;
  8.       if  localInt < 10  then
  9.          f(localInt);
  10.  
  11.      result := localInt;
  12.   end;
  13. begin
  14.   f(1);
  15. end;  
  16.  
  17.  
« Last Edit: February 14, 2026, 03:32:31 pm by BubikolRamios »
lazarus 3.2-fpc-3.2.2-win32/win64

WooBean

  • Sr. Member
  • ****
  • Posts: 303
Re: Does not go out of function
« Reply #7 on: February 14, 2026, 03:42:16 pm »
I suggest  a change to see what happened:

Code: Pascal  [Select][+][-]
  1.     procedure TForm2.Button22Click(Sender: TObject);
  2.     var
  3.       k:integer;
  4.       function f(j: integer): integer;
  5.       var
  6.         localInt : integer = 0;
  7.         i: integer;
  8.       begin
  9.           localInt := j +1;
  10.           if  localInt < 10  then
  11.              f(localInt);
  12.      
  13.          result := localInt;
  14.       end;
  15.     begin
  16.       k:=f(1);
  17.       Button22.Caption:=IntToStr(k); // here we know what really happened
  18.     end;    
  19.  
Platforms: Win7/64, Linux Mint 22.1 Xia

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12208
  • Debugger - SynEdit - and more
    • wiki
Re: Does not go out of function
« Reply #8 on: February 14, 2026, 03:43:52 pm »
Here, I managed to reproduce.

Put breakpoint ono "result := localInt;", ok when 10, lands there.
Do not remove break point, press F9, observe localInt value, goes backwarda 9,8,7,.....
Well that is expected and correct.

If you open the "Call Stack" window from menu "View > Debug Windows" then you can see some more details.

Here is what happens

Code: Text  [Select][+][-]
  1. Line 14; "f(1);"
  2.   Line 7: "localInt := j +1;"   value = 2
  3.   Line 8: "     if  localInt < 10  then" is true
  4.   Line 9: "         f(localInt);" recursive call
  5.        Entering RECURSION,
  6.        - there is a NEW variable localInt
  7.        - localInt of the outer call will not be modified
  8.     Line 7: "localInt := j +1;"   value = 3  for the NEW localInt
  9.        At this point the OUTER LOCALINT is still 2
  10.     Line 8: "     if  localInt < 10  then" is true
  11.     Line 9: "         f(localInt);" recursive call
  12.       Line 7: "localInt := j +1;"   value = 4  for YET ANOTHER NEW localInt
  13.        At this point there are TWO  outer LOCALINT with values 2 and 3
  14.       Line 8: "     if  localInt < 10  then" is true
  15.       Line 9: "         f(localInt);" recursive call
  16.  .....
  17.  

When you finally hit
  Line 11: "     result := localInt;"
That is the innermost recursive call, and the value is 10

Then each F9 goes OUT one level of recursion, and each outer call has its own variable "localInt", which is one less than the inner one.

So you get down until "localInt = 2" => which is the value it had in the very first entry of "f".


In the stack you can see how many callers there are, and you can see the value of the parameter "j".

You can select any frame (line) in the stack as "current", and then you can inspect "localInt" for each frame. And you will see that all the values are there from 2 to 10.


Quote
While if you put additional breakpoints anywhere, looks like everything that happens is on "breaked line" and nowhere else.
Obviously there is no - anywhere.
If you put the breakpoint before line 9 or on line 9 (where the recursive call happens) then the recursion has not yet entered, and you will watch going into it. SO things happen in the order of going in.

Quote

And it does not go out as said at OP, when one would expect.
The 0 instead of 10 comes out even if there are no breakpoins.
Actually 2 comes out? At least for me?

Quote
How to fix that ?

Code: Pascal  [Select][+][-]
  1. procedure TForm2.Button22Click(Sender: TObject);
  2.   function f(j: integer): integer;
  3.   var
  4.     localInt : integer = 0;
  5.     i: integer;
  6.   begin
  7.       localInt := j +1;
  8.       if  localInt < 10  then
  9.          f(localInt);
  10.  
  11.      result := localInt;
  12.   end;
  13. begin
  14.   f(1);
  15. end;  
  16.  
  17.  


Maybe you want code like

Code: Pascal  [Select][+][-]
  1.   function f(j: integer): integer;
  2.   var
  3.     localInt : integer = 0;
  4.     i: integer;
  5.   begin
  6.       localInt := j +1;
  7.       if  localInt < 10  then
  8.          localInt := f(localInt);
  9.  
  10.      result := localInt;
  11.   end;
  12.  

or
Code: Pascal  [Select][+][-]
  1.   function f(j: integer): integer;
  2.   var
  3.     localInt : integer = 0;
  4.     i: integer;
  5.   begin
  6.       localInt := j +1;
  7.       result := localInt;
  8.       if  localInt < 10  then
  9.          result := f(localInt);
  10.   end;
  11.  

Zvoni

  • Hero Member
  • *****
  • Posts: 3315
Re: Does not go out of function
« Reply #9 on: February 16, 2026, 08:18:04 am »
If i understood it correctly, OP wants to break the whole recursion, when he reaches the "Result:=Something"-Line, with the value in that last "Result" being transported back to the initial call.

A var/out Param in the Function, transporting the result back, and the Function-Result itself being a Boolean indicating "Yeah, i'm done"?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

440bx

  • Hero Member
  • *****
  • Posts: 6159
Re: Does not go out of function
« Reply #10 on: February 16, 2026, 08:49:08 am »
If i understood it correctly, OP wants to break the whole recursion, when he reaches the "Result:=Something"-Line, with the value in that last "Result" being transported back to the initial call.
That's the way I understood his code as well.

His code seems to be a variation of tail recursion triggered by the condition in the "if" being true.  If that is correct then, he can have an infinite loop controlled by the "if" which would simply break out of the loop when appropriate thereby causing the function to return the desired value.

The whole thing, as he has it, seems way more complicated than it needs to be.

HTH.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018