From Surf Wiki (app.surf) — the open knowledge base
Goto
One-way software control-flow statement
One-way software control-flow statement
the programming statement in high-level languages
In computer programming, goto is a control flow statement that transfers control to another line of source code. Unlike a function call that supports returning to the point of call, goto does not. The statement is denoted differently by programming language; some use lowercase (), some use uppercase (), and others are case-insensitive. A few languages make the statement two words (i.e. ).
A goto statement is included in a language, primarily, to provide access to the machine code jump instruction (a.k.a. branch or transfer), but due to potential problems with the use of jump semantics, languages have over time been augmented with other flow-control mechanisms intended to replace the need for and use of goto. Many modern languages do not include a goto statement at all. Many languages that include goto, restrict its use in order to limit the problems that its use might incur. Further, as its use is generally considered a poor choice, software developers tend to avoid using it even when using a language that provides it.
In general, use of goto is considered a poor choice as it leads to code with higher cognitive load and more bugs than code that uses more structured flow-control. The use of goto was common in the early days of computing, but via the concerted effort of the structured programming movement in the 1960s and 1970s, that aimed to replace goto with more structured flow-control, its use has declined significantly. None-the-less, goto is still used today, but generally limited to specific scenarios.
The structured program theorem proved that the goto statement is not necessary to write programs that can be expressed as flow charts; some combination of the three programming constructs of sequence, selection, and iteration are sufficient for any computation that can be performed by a Turing machine, with the caveat that code duplication and additional variables may be required.
Language support
Support of goto varies by language. Languages designed long ago tend to have unrestricted support and newer languages tend to have restricted or no support. For example, C does not permit a jump to a label in a different function.
C# and Visual Basic .NET both support goto. However, they do not allow jumping to a label outside of the containing scope, and respects object disposal and finally constructs, making it significantly less powerful and less dangerous than goto in other languages. They also make and keywords labels, whose scope is the enclosing switch statement. or is used as a replacement for implicit fallthrough, which is not allowed.
Many languages lack goto semantics. Java, has a reserved word but it is not usable, although compiled .class files generate goto and label statements. Python does not support goto, although there are several joke modules that provide it. PHP did not support goto until version 5.3.
PL/I has a goto statement that unwinds the stack for an out-of-block transfer and does not permit a transfer into a block.
Most languages that have a goto-semantics statement use the keyword goto, but other syntax is used; particularly in older languages. For example, MAD uses , and APL uses a right-pointing arrow, →.
Functional programming languages such as Scheme generally do not have goto, instead using continuations.
Computed and assigned{{anchor |computed-goto}}{{anchor |assigned-goto}}
In Fortran, a computed goto jumps to one of several labels in a list, based on the value of an expression. An example is goto (20,30,40) i. The equivalent construct in C is the switch statement, and in newer Fortran a SELECT CASE construct is the recommended syntactical alternative. BASIC had a 'On GoTo' statement that achieved the same goal, but in Visual Basic this construct is no longer supported.
In versions prior to Fortran 95, Fortran also had an assigned goto variant that transfers control to a statement label (line number) which is stored in (assigned to) an integer variable. Jumping to an integer variable that had not been ASSIGNed to was unfortunately possible, and was a major source of bugs involving assigned goto statements. The Fortran assign statement only allows a constant (existing) line number to be assigned to the integer variable. However, some compilers allowed accidentally treating this variable as an integer thereafter, for example increment it, resulting in unspecified behavior at goto time. The following code demonstrates the behavior of the goto i when line i is unspecified:
assign 200 to i
i = i+1
goto i ! unspecified behavior
200 write(*,*) "this is valid line number"
Several C compilers implement two non-standard C/C++ extensions relating to goto statements originally introduced by gcc. The GNU extension allows the address of a label inside the current function to be obtained as a void* using the unary, prefix label value operator &&. The goto instruction is also extended to allow jumping to an arbitrary void* expression. This C extension is referred to as a computed goto in documentation of the C compilers that support it; its semantics are a superset of Fortran's assigned goto, because it allows arbitrary pointer expressions as the goto target, while Fortran's assigned goto doesn't allow arbitrary expressions as jump target. As with the standard goto in C, the GNU C extension allows the target of the computed goto to reside only in the current function. Attempting to jump outside the current function results in unspecified behavior.
Some variants of BASIC also support a computed goto in the sense used in GNU C, i.e. in which the target can be any line number, not just one from a list. For example, in MTS BASIC one could write GOTO i*1000 to jump to the line numbered 1000 times the value of a variable i (which might represent a selected menu option, for example).
PL/I label variables achieve the effect of the computed or assigned goto.
ALTER
Up to the 1985, ANSI standard COBOL had the statement which could be used to change the destination of a , which had to be in a paragraph by itself. The statement was deemed obsolete in the COBOL 1985 standard and deleted in 2002 (see COBOL self-modifying code). The feature, which allowed polymorphism, was frequently condemned and seldom used.
Perl goto
Perl has a goto statement that takes a function name and transfers control by effectively substituting one function call for another (a tail call). The new function does not return to the goto, but instead to the place from which the original function was called.
Emulated goto
There are several languages that do not directly support goto, but goto emulation provides some goto-like capability, albeit with restrictions. One can emulate goto in Java, JavaScript, and Python.
PL/I label variable
The PL/I data type can be used to implement both assigned and computed goto, and PL/I allows branching outside of the current block. A procedure can receive a label as an argument which can then exit with a branch. The value of a label variable includes the address of a stack frame, and a goto out of block pops the stack.
The following implements an assigned goto.
declare where label;
where = somewhere;
goto where;
...
somewhere:
...
The following implements a computed goto.
declare where (5) label;
declare inx fixed;
where(1) = abc;
where(2) = xyz;
...
goto where(inx);
...
abc:
...
xyz:
...
Another way to get an equivalent result is by using a label constant array which doesn't use a variable:
declare inx fixed;
...
goto where(inx);
...
where(1):
...
where(2):
...
Examples
Syntax varies by language, but often follows a similar pattern. The target of control is identified as a label or a line number.
In a DOS batch file, goto directs execution to a label; an identifier prefixed with a colon. The target of the goto can be a variable. The following uses goto to implement multi-path branching via a computed goto.
@echo off
SET D8str=%date%
SET D8dow=%D8str:~0,3%
FOR %%D in (Mon Wed Fri) do if "%%D" == "%D8dow%" goto SHOP%%D
echo Today, %D8dow%, is not a shopping day.
goto end
:SHOPMon
echo buy pizza for lunch - Monday is Pizza day.
goto end
:SHOPWed
echo buy Calzone to take home - today is Wednesday.
goto end
:SHOPFri
echo buy Seltzer in case somebody wants a zero calorie drink.
:end
Criticism
At the pre-ALGOL meeting held in 1959, Heinz Zemanek explicitly cast doubt on the necessity of goto statements, but at the time, no one paid attention to his remark, including Edsger W. Dijkstra, who later became the iconic opponent of goto. The 1970s and 1980s saw a decline in the use of goto statements in favor of the structured programming paradigm, with goto criticized as leading to unmaintainable spaghetti code. Some programming style coding standards, for example the GNU Pascal Coding Standards, recommend against the use of goto statements. The Böhm–Jacopini proof (1966) did not settle the question of whether to adopt structured programming for software development, partly because the construction was more likely to obscure a program than to improve it because its application requires the introduction of additional local variables. It did, however, spark a prominent debate among computer scientists, educators, language designers and application programmers that saw a slow but steady shift away from the formerly ubiquitous use of the goto. Probably the most famous criticism of goto is a 1968 letter by Edsger Dijkstra called Go-to statement considered harmful. In that letter, Dijkstra argued that unrestricted goto statements should be abolished from higher-level languages because they complicated the task of analyzing and verifying the correctness of programs (particularly those involving loops). The letter itself sparked a debate, including a GOTO Considered Harmful' Considered Harmful" letter sent to Communications of the ACM (CACM) in March 1987, as well as further replies by other people, including Dijkstra's On a Somewhat Disappointing Correspondence.
An alternative viewpoint is presented in Donald Knuth's Structured Programming with go to Statements, which analyzes many common programming tasks and finds that in some of them goto is the optimal language construct to use. In The C Programming Language, Brian Kernighan and Dennis Ritchie warn that goto is "infinitely abusable", but also suggest that it could be used for end-of-function error handlers and for multi-level breaks from loops. These two patterns can be found in numerous subsequent books on C by other authors; a 2007 introductory textbook notes that the error handling pattern is a way to work around the "lack of built-in exception handling within the C language". Other programmers, including Linux kernel designer and coder Linus Torvalds or software engineer and book author Steve McConnell, also object to Dijkstra's point of view, stating that goto can be a useful language feature, improving program speed, size and code clarity, but only when used in a sensible way by a comparably sensible programmer. According to computer science professor John Regehr, in 2013, there were about 100,000 instances of goto in the Linux kernel code.
Other academics took a more extreme viewpoint and argued that even instructions like break and return from the middle of loops are bad practice as they are not needed in the Böhm–Jacopini result, and thus advocated that loops should have a single exit point. For instance, Bertrand Meyer wrote in his 2009 textbook that instructions like break and continue "are just the old goto in sheep's clothing". A slightly modified form of the Böhm–Jacopini result, however, allows the avoidance of additional variables in structured programming, as long as multi-level breaks from loops are allowed. Because some languages like C don't allow multi-level breaks via their break keyword, some textbooks advise the programmer to use goto in such circumstances. The MISRA C 2004 standard bans goto, continue, as well as multiple return and break statements. The 2012 edition of the MISRA C standard downgraded the prohibition on goto from "required" to "advisory" status; the 2012 edition has an additional, mandatory rule that prohibits only backward, but not forward jumps with goto.
FORTRAN introduced structured programming constructs in 1978, and in successive revisions the relatively loose semantic rules governing the allowable use of goto were tightened; the "extended range" in which a programmer could use a goto to leave and re-enter a still-executing DO loop was removed from the language in 1978, and by 1995 several forms of Fortran goto, including the computed goto and the assigned goto, had been deleted. Some widely used modern programming languages such as Java and Python lack the goto statement – though most provide some means of breaking out of a selection, or either breaking out of or moving on to the next step of an iteration. The viewpoint that disturbing the control flow in code is undesirable may be seen in the design of some programming languages, for instance Ada visually emphasizes label definitions using angle brackets.
Entry 17.10 in comp.lang.c FAQ list addresses the issue of goto use directly, stating
More accepted patterns
While overall use of goto has declined, there are situations in which goto provides a good way to express program logic. While it is possible to express the logic without goto, the equivalent code is longer or more difficult to understand. Situations in which goto is more likely to be considered acceptable include:
-
Error handling, particularly cleanup code such as resource deallocation.
-
Reducing code duplication.
-
Implementing a finite-state machine using a state transition table and goto to switch between states (in absence of tail call elimination), particularly in automatically generated C code. For example, goto in the canonical LR parser.
-
Implementing multi-level break and continue if not directly supported in the language; this is a common idiom in C. Although Java reserves the goto keyword, it doesn't actually implement it. Instead, Java implements labelled break and labelled continue statements. According to the Java documentation, the use of goto statements for multi-level breaks was the most common (90%) use of goto statements in C. Java was not the first language to take this approach—forbidding goto, but providing multi-level breaks— the BLISS programming language (more precisely the BLISS-11 version thereof) preceded it in this respect.
-
Surrogates for single-level break or continue (retry) statements when the potential introduction of additional loops could incorrectly affect the control flow. This practice has been observed in NetBSD code.
-
Popping the stack in languages such as Algol and PL/I.
-
Specialized scripting languages that operate in a linear manner, such as a dialogue system for video games.
These uses are relatively common in C, but much less common in C++ or other languages with higher-level features. However, throwing and catching an exception inside a function can be extraordinarily inefficient in some languages; a prime example is Objective-C, where a goto is a much faster alternative.
Another use of goto is to modify poorly factored legacy code, where avoiding a goto would require extensive refactoring or code duplication. For example, given a large function where only certain code is of interest, a goto allows one to jump to or from only the relevant code, without otherwise modifying the function. This usage is considered code smell, but finds occasional use.
Alternatives
Structured programming
The structured programming movement aimed to eliminate the need for and use of the goto statement by introducing control structures to a language such as:
; Selection: Such as the conditional statement (i.e. if-then-else) and the switch statement
; Iteration: Loop statements such as the for loop, while loop and do while loop.
; Premature exit: terminate execution of control structure or a single iteration
Ask Mako anything about Goto — get instant answers, deeper analysis, and related topics.
Research with MakoFree with your Surf account
Create a free account to save articles, ask Mako questions, and organize your research.
Sign up freeThis content may have been generated or modified by AI. CloudSurf Software LLC is not responsible for the accuracy, completeness, or reliability of AI-generated content. Always verify important information from primary sources.
Report