### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### furious programming

• Hero Member
• Posts: 777
##### 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 2.2.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2025.

#### AlexTP

• Hero Member
• Posts: 2287
##### Re: Non-local goto example needed
« Reply #1 on: May 25, 2023, 04:00:44 pm »
« Last Edit: May 25, 2023, 04:02:15 pm by AlexTP »

#### Blaazen

• Hero Member
• Posts: 3235
• POKE 54296,15
##### 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/

#### furious programming

• Hero Member
• Posts: 777
##### 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 2.2.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2025.

#### Bart

• Hero Member
• Posts: 5132
##### 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: 3235
• POKE 54296,15
##### 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/

#### furious programming

• Hero Member
• Posts: 777
##### 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 2.2.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2025.

#### PascalDragon

• Hero Member
• Posts: 5273
• 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: 5273
• 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!');
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

• Hero Member
• Posts: 11073
• 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 »

#### furious programming

• Hero Member
• Posts: 777
##### 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 2.2.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2025.

#### marcov

• Hero Member
• Posts: 11073
• 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.