Recent

Author Topic: Non-local goto example needed  (Read 2979 times)

flowCRANE

  • Hero Member
  • *****
  • Posts: 883
Non-local goto example needed
« on: May 25, 2023, 03:53:11 pm »
Hi. I know that the Free Pascal supports non-local goto when {$MODESWITCH NONLOCALGOTO} is used, but I can't imagine the situation when such a jump is usable. Can somebody provide a compilable usage example of such a non-local goto? I can't find any useful information related to the Free Pascal both in the language spec or even in Google.
« Last Edit: May 25, 2023, 03:55:05 pm by furious programming »
Lazarus 3.4 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL.


Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Non-local goto example needed
« Reply #2 on: May 25, 2023, 04:33:24 pm »
Code: Pascal  [Select][+][-]
  1. program Find;
  2. {$modeswitch nonlocalgoto}
  3. label loop;
  4.  
  5.   procedure Test(i: Integer);
  6.  
  7.     procedure Test2(i: Integer);
  8.  
  9.       procedure Test3(i: Integer);
  10.       begin
  11.         if (i>=10) and (i<=99) then writeln(i);
  12.         goto loop;
  13.       end;
  14.  
  15.     begin
  16.       if (i mod 3)=0 then Test3(i);
  17.     end;
  18.  
  19.   begin
  20.     if (i mod 2)=1 then Test2(i);
  21.   end;
  22.  
  23. const A: array[0..9] of Integer = (5, 8, 9, 15, 18, 25, 28, 33, 37, 105);
  24. var i: Integer;
  25. begin
  26.   //find odd and two digits multiplies of three
  27.   for i:=0 to high(A) do
  28.     begin
  29.       Test(A[i]);
  30.       loop:
  31.     end;
  32. end.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

flowCRANE

  • Hero Member
  • *****
  • Posts: 883
Re: Non-local goto example needed
« Reply #3 on: May 25, 2023, 04:56:06 pm »
Is this feature limited to the nested routines only?
Lazarus 3.4 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL.

Bart

  • Hero Member
  • *****
  • Posts: 5465
    • Bart en Mariska's Webstek
Re: Non-local goto example needed
« Reply #4 on: May 25, 2023, 04:58:51 pm »
Hi. I know that the Free Pascal supports non-local goto when {$MODESWITCH NONLOCALGOTO} is used, but I can't imagine the situation when such a jump is usable.
When porting old BASIC spaghetti code perhaps  :)

Bart

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Non-local goto example needed
« Reply #5 on: May 25, 2023, 05:00:20 pm »
Quote
Is this feature limited to the nested routines only?

I didn't try but probably yes, since docs says:
Quote
Overview: It is now possible to goto to a label defined in another procedure, e.g. to quickly exit from a deeply nested procedure to a less deeply nested one.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

flowCRANE

  • Hero Member
  • *****
  • Posts: 883
Re: Non-local goto example needed
« Reply #6 on: May 26, 2023, 09:02:26 pm »
This is why I'm asking, because there is ”e.g. to quickly exit from a deeply nested procedure” but not ”only to quickly exit from a deeply nested procedure”. Thank you for examples.
Lazarus 3.4 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5750
  • Compiler Developer
Re: Non-local goto example needed
« Reply #7 on: May 26, 2023, 09:29:02 pm »
This is why I'm asking, because there is ”e.g. to quickly exit from a deeply nested procedure” but not ”only to quickly exit from a deeply nested procedure”. Thank you for examples.

Please note that non-local-gotos mainly exist for compatibility with other language dialects and if used in a cross-procedural manner in Object Pascal code this might influence Object Pascal features (like cleanup of managed types, exception stack, etc.). So even if it might be possible, it isn't necessarily a good idea.

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: Non-local goto example needed
« Reply #8 on: May 26, 2023, 10:17:36 pm »
For the demonstrated purpose setjmp()-longjmp() should be better, because it saves/restores registers and gives a return value.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5750
  • Compiler Developer
Re: Non-local goto example needed
« Reply #9 on: May 26, 2023, 10:23:40 pm »
For the demonstrated purpose setjmp()-longjmp() should be better, because it saves/restores registers and gives a return value.

non-local-gotos are implemented using setjmp/longjmp.

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: Non-local goto example needed
« Reply #10 on: May 26, 2023, 10:43:47 pm »
For the demonstrated purpose setjmp()-longjmp() should be better, because it saves/restores registers and gives a return value.

non-local-gotos are implemented using setjmp/longjmp.

I have never tried nonlocal gotos. Theoretically these could be used to jump into a loop or into a procedure, which is a horrible idea for me.

With setjmp/longjmp you must initialize jmp_buf, which stores the location and registers and you can return and you get a return value. You can only jump back to a location, where you have been before you cannot jump to arbitrary locations.
This is very different.

Experimental code example:  Variable "pos" is the jmp_buf, which stores registers and execution point.

Code: Pascal  [Select][+][-]
  1.     while True do
  2.  
  3.     try
  4.       while (true) do
  5.       begin
  6.         if setjmp(pos) > 0 then    //"pos" stores registers and execution point here into jmp_buf record.
  7.            writeln('Error! Please input integer number!');
  8.         readln(N);
  9.        ...... //code which may raise exception can modify "pos" so
  10.        ......//the exception always returns to the point where it was raised.
  11.       end;
  12.     except
  13.       on E: EInOutError do
  14.       begin
  15.         longjmp(pos, 1);
  16.         // Writeln(E.ClassName, ': ', E.Message);
  17.       end;
  18.     end;

Simplifies error handling, if you have multiple "readln" lines which can raise exceptions in the code.
Can you do this with nonlocal goto?
« Last Edit: May 26, 2023, 11:43:05 pm by Peter H »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11930
  • FPC developer.
Re: Non-local goto example needed
« Reply #11 on: May 26, 2023, 11:35:47 pm »
You don't jump to a location where you have been before, but you jump back to a frame where you have been before.

Peter H

  • Sr. Member
  • ****
  • Posts: 272
Re: Non-local goto example needed
« Reply #12 on: May 26, 2023, 11:46:10 pm »
You don't jump to a location where you have been before, but you jump back to a frame where you have been before.

I jump back into a location (execution point) whis is indeed inside a frame where I have been before.
I would assume with ordinary "nonlocal goto" this is not possible without problems.

It must be used with care.
Of course you must not jump back into a subroutine whose stackframe is already destroyed.
When I am inside the "except" block, all local variables are still accessible, so the stackframe is not destroyed and therefore I can do this securely.
« Last Edit: May 27, 2023, 12:05:46 am by Peter H »

flowCRANE

  • Hero Member
  • *****
  • Posts: 883
Re: Non-local goto example needed
« Reply #13 on: May 27, 2023, 01:20:58 pm »
non-local-gotos are implemented using setjmp/longjmp.

What about exceptions? They are also implemented in this way?
Lazarus 3.4 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11930
  • FPC developer.
Re: Non-local goto example needed
« Reply #14 on: May 27, 2023, 01:32:55 pm »
non-local-gotos are implemented using setjmp/longjmp.

What about exceptions? They are also implemented in this way?

Just like with gcc, it is the last resort implementation, depending on target.  E.g. Windows uses table driven SEH exceptions.  For mainstream linux there was dwarf EH frame support iirc, but I don't know if that is live yet.

 

TinyPortal © 2005-2018