Difference between revisions of "Goto"

From Free Pascal wiki
Jump to navigationJump to search
(Translated German text; clarified that "previously declared label" need not mean that the label itself lies before the goto statement.)
(→‎See also: insert Exit)
 
(12 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{goto}}
 
{{goto}}
<br>
+
 
'''Goto''' is an unconditional jump to a previously declared [[label]] (either before or after the goto command).
+
<syntaxhighlight inline lang="pascal">goto</syntaxhighlight> is an unconditional jump to a previously declared [[Label|<syntaxhighlight inline lang="pascal">label</syntaxhighlight>]] (either before or after the <syntaxhighlight inline lang="pascal">goto</syntaxhighlight> command).
<br>
+
It is a [[Reserved words|reserved word]].
Example for the declaration of a label and use of goto:
+
 
<br>
+
Usage of <syntaxhighlight inline lang="pascal">goto</syntaxhighlight> in high-level programming languages such as Pascal is highly discredited, since control structures of all sorts are available.
<syntaxhighlight>
+
 
var
+
The last situation a <syntaxhighlight inline lang="pascal">goto</syntaxhighlight> is agreed with bad grace to be a significant system error, where a “graceful exit” is better than causing a system breakdown.
  fWaterIsBoiling: Boolean;
+
 
+
As an example, here an excerpt from FPC’s code base {{gitlab|blob|FPC|release_3_2_0/rtl/inc/extres.inc#L324-376|<tt>rtl/inc/extres.inc</tt>}}]:
label
+
<syntaxhighlight lang="pascal" line start="324">procedure InitResources;</syntaxhighlight>
   SwitchOffKettle;
+
<syntaxhighlight lang="pascal" line start="328" highlight="1">label ExitErrMem, ExitErrFile, ExitNoErr;
   
+
begin</syntaxhighlight>
begin
+
<syntaxhighlight lang="pascal" line start="339" highlight="2">  ResHeader:=GetMem(sizeof(TExtHeader));
   ...
+
   if ResHeader=nil then goto ExitErrFile;</syntaxhighlight>
  if fWaterIsBoiling = True then Goto SwitchOffKettle;
+
<syntaxhighlight lang="pascal" line start="366" highlight="6"> goto ExitNoErr;
   ...
+
 
SwitchOffKettle:
+
   ExitErrMem:
  ...
+
    FreeMem(ResHeader);
end;
+
    ResHeader:=nil;
</syntaxhighlight>
+
   ExitErrFile:
[[category:Pascal]]
+
    {$I-}
 +
    Close(fd);
 +
    {$I+}
 +
  ExitNoErr:
 +
end;</syntaxhighlight>
 +
According to the value of {{Doc|package=RTL|unit=system|identifier=returnnilifgrowheapfails|text=<syntaxhighlight inline lang="pascal">returnNilIfGrowHeapFails</syntaxhighlight>}} {{Doc|package=RTL|unit=system|identifier=getmem|text=<syntaxhighlight inline lang="pascal">getMem</syntaxhighlight>}} possibly may return [[Nil|<syntaxhighlight inline lang="pascal">nil</syntaxhighlight>]].
 +
Instead of placing ''everything'' in a “success”-branch, a couple <syntaxhighlight inline lang="pascal">goto</syntaxhighlight> instructions were chosen.
 +
 
 +
== See also ==
 +
* [[Exit|<syntaxhighlight lang="delphi" inline>exit</syntaxhighlight>]]
 +
* [[sGoto|<syntaxhighlight lang="pascal" inline>{$goto}</syntaxhighlight> compiler directive]]
 +
* {{Doc|package=RTL|unit=system|identifier=longjmp|text=<syntaxhighlight lang="pascal" inline>system.longJmp</syntaxhighlight>}}
 +
 
 +
[[Category: Code]]

Latest revision as of 00:36, 25 January 2022

Deutsch (de) English (en) français (fr) русский (ru)

goto is an unconditional jump to a previously declared label (either before or after the goto command). It is a reserved word.

Usage of goto in high-level programming languages such as Pascal is highly discredited, since control structures of all sorts are available.

The last situation a goto is agreed with bad grace to be a significant system error, where a “graceful exit” is better than causing a system breakdown.

As an example, here an excerpt from FPC’s code base rtl/inc/extres.inc]:

324procedure InitResources;
328label ExitErrMem, ExitErrFile, ExitNoErr;
329begin
339  ResHeader:=GetMem(sizeof(TExtHeader));
340  if ResHeader=nil then goto ExitErrFile;
366  goto ExitNoErr;
367
368  ExitErrMem:
369    FreeMem(ResHeader);
370    ResHeader:=nil;
371  ExitErrFile:
372    {$I-}
373    Close(fd);
374    {$I+}
375  ExitNoErr:
376end;

According to the value of returnNilIfGrowHeapFails getMem possibly may return nil. Instead of placing everything in a “success”-branch, a couple goto instructions were chosen.

See also