Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Goto

From Wikipedia, the free encyclopedia
(Redirected fromGOTO)
One-way software control-flow statement
This article is about the programming statement in high-level languages. For other uses, seeGoto (disambiguation).
"GOTO" key on the 1982ZX Spectrum home computer, implemented with nativeBASIC (one-key command entry).

Incomputer programming,goto is acontrol flow statement that transferscontrol to another line ofsource code. Unlike afunction call that supportsreturning to the point of call, goto does not. The statement is denoted differently byprogramming language; some use lowercase (goto), some use uppercase (GOTO), and others are case-insensitive. A few languages make the statement two words (i.e.GO TO).

A goto statement is included in a language, primarily, to provide access to themachine codejump 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 highercognitive load and morebugs 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 thestructured 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 specificscenarios.

Thestructured program theorem proved that the goto statement is not necessary to write programs that can be expressed asflow charts; some combination of the three programming constructs of sequence, selection, and iteration are sufficient for any computation that can be performed by aTuring machine, with the caveat thatcode duplication and additional variables may be required.[1]

Language support

[edit]

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.[2][3]

C# andVisual Basic .NET both support goto.[4][5] 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 makecase anddefault keywords labels, whose scope is the enclosingswitch statement.goto case orgoto default is used as a replacement for implicitfallthrough, which is not allowed.

Many languages lack goto semantics.Java, has areserved wordgoto but it is not usable, although compiled.class files generate goto and label statements.[clarification needed][6] Python does not support goto, although there are several joke modules that provide it.[7][8]PHP did not support goto until version 5.3.[9]

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 keywordgoto, but other syntax is used; particularly in older languages. For example,MAD usesTRANSFER TO,[10] andAPL uses a right-pointing arrow,.

Functional programming languages such as Scheme generally do not have goto, instead using continuations.

Computed and assigned

[edit]
See also:Branch table

InFortran, acomputed goto jumps to one of several labels in a list, based on the value of an expression. An example isgoto (20,30,40) i.[11] The equivalent construct in C is theswitch statement, and in newer Fortran aSELECT CASE construct is the recommended syntactical alternative.[12]BASIC had a'On GoTo' statement that achieved the same goal, but inVisual Basic this construct is no longer supported.[13]

In versions prior to Fortran 95, Fortran also had anassigned 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.[14] The Fortranassign 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 thegoto i when linei is unspecified:

assign200toii=i+1gotoi! unspecified behavior200write(*,*)"this is valid line number"

Several C compilers implement two non-standard C/C++ extensions relating to goto statements originally introduced bygcc.[15] The GNU extension allows the address of a label inside the current function to be obtained as avoid* using the unary, prefixlabel value operator&&. The goto instruction is also extended to allow jumping to an arbitraryvoid* expression. This C extension is referred to as acomputed 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.[16] 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.[16]

Some variants of BASIC also support a computed goto in the sense used in GNU C, i.e. in which the target can beany line number, not just one from a list. For example, inMTS BASIC one could writeGOTO i*1000 to jump to the line numbered 1000 times the value of a variablei (which might represent a selected menu option, for example).[17]

PL/Ilabel variables achieve the effect of the computed or assigned goto.

ALTER

[edit]

Up to the 1985, ANSI standardCOBOL had theALTER statement which could be used to change the destination of aGO TO, which had to be in a paragraph by itself. TheALTER statement was deemed obsolete in the COBOL 1985 standard and deleted in 2002 (seeCOBOL self-modifying code). The feature, which allowedpolymorphism, was frequently condemned and seldom used.[18]

Perl goto

[edit]

Perl has a goto statement that takes a function name and transfers control by effectively substituting one function call for another (atail call). The new function does not return to the goto, but instead to the place from which the original function was called.[19][clarification needed]

Emulated goto

[edit]

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,[20] JavaScript,[21] and Python.[7][8]

PL/I label variable

[edit]

ThePL/I data typelabel 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.

declarewherelabel;where=somewhere;gotowhere;...somewhere:...

The following implements a computed goto.

declarewhere(5)label;declareinxfixed;where(1)=abc;where(2)=xyz;...gotowhere(inx);...abc:...xyz:...

Another way to get an equivalent result is by using alabel constant array which doesn't use alabel variable:

declareinxfixed;...gotowhere(inx);...where(1):...where(2):...

Examples

[edit]

Syntax varies by language, but often follows a similar pattern. The target of control is identified as alabel or aline number.

In a DOSbatch 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 offSETD8str=%date%SETD8dow=%D8str:~0,3%FOR%%Din(Mon Wed Fri)doif"%%D"=="%D8dow%"gotoSHOP%%Decho Today,%D8dow%, is not a shopping day.gotoend:SHOPMonecho buy pizza for lunch - Monday is Pizza day.gotoend:SHOPWedecho buy Calzone to take home - today is Wednesday.gotoend:SHOPFriecho buy Seltzer in case somebody wants a zero calorie drink.:end

Criticism

[edit]

At thepre-ALGOL meeting held in 1959,Heinz Zemanek explicitly cast doubt on the necessity of goto statements, but at the time, no one[citation needed] paid attention to his remark, includingEdsger W. Dijkstra, who later became the iconic opponent of goto.[22] The 1970s and 1980s saw a decline in the use of goto statements in favor of thestructured programmingparadigm, with goto criticized as leading to unmaintainablespaghetti code. Someprogramming style coding standards, for example the GNU Pascal Coding Standards, recommend against the use of goto statements.[23] TheBö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.[24] 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 calledGo-to statement considered harmful.[22] 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).[25] The letter itself sparked a debate, including a"'GOTO Considered Harmful' Considered Harmful" letter[26] sent toCommunications of theACM (CACM) in March 1987, as well as further replies by other people, including Dijkstra'sOn a Somewhat Disappointing Correspondence.[27]

An alternative viewpoint is presented inDonald Knuth'sStructured Programming with go to Statements, which analyzes many common programming tasks and finds that in some of them goto is the optimallanguage construct to use.[28] InThe C Programming Language,Brian Kernighan andDennis 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.[29] These two patterns can be found in numerous subsequent books on C by other authors;[30][31][32][33] 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".[30] Other programmers, includingLinux kernel designer and coderLinus Torvalds or software engineer and book authorSteve 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.[34][35] According to computer science professorJohn Regehr, in 2013, there were about 100,000 instances of goto in the Linux kernel code.[36]

Other academics took a more extreme viewpoint and argued that even instructions likebreak andreturn 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.[37] For instance,Bertrand Meyer wrote in his 2009 textbook that instructions likebreak andcontinue "are just the old goto in sheep's clothing".[38] 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.[39] Because some languages like C don't allow multi-level breaks via theirbreak keyword, some textbooks advise the programmer to use goto in such circumstances.[33] TheMISRA C 2004 standard bans goto,continue, as well as multiplereturn andbreak statements.[40] 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.[41][42]

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,[43] and by 1995 several forms of Fortran goto, including the computed goto and the assigned goto, had been deleted.[44] Some widely used modern programming languages such asJava andPython lack the goto statement – though most provide some means of breaking out of a selection, or eitherbreaking out of ormoving 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 instanceAda[45] visually emphasizes label definitions usingangle brackets.

Entry 17.10 in comp.lang.c FAQ list[46] addresses the issue of goto use directly, stating

Programming style, like writing style, is somewhat of an art and cannot be codified by inflexible rules, although discussions about style often seem to center exclusively around such rules. In the case of the goto statement, it has long been observed that unfettered use of goto's quickly leads to unmaintainable spaghetti code. However, a simple, unthinking ban on the goto statement does not necessarily lead immediately to beautiful programming: an unstructured programmer is just as capable of constructing a Byzantine tangle without using any goto's (perhaps substituting oddly-nested loops and Boolean control variables, instead). Many programmers adopt a moderate stance: goto's are usually to be avoided, but are acceptable in a few well-constrained situations, if necessary: as multi-level break statements, to coalesce common actions inside a switch statement, or to centralize cleanup tasks in a function with several error returns. (...) Blindly avoiding certain constructs or following rules without understanding them can lead to just as many problems as the rules were supposed to avert. Furthermore, many opinions on programming style are just that: opinions. They may be strongly argued and strongly felt, they may be backed up by solid-seeming evidence and arguments, but the opposing opinions may be just as strongly felt, supported, and argued. It's usually futile to get dragged into "style wars", because on certain issues, opponents can never seem to agree, or agree to disagree, or stop arguing.

More accepted patterns

[edit]

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:[34][47]

  • Implementing multi-level break and continue if not directly supported in the language; this is a common idiom in C.[33] Although Java reserves the goto keyword, it doesn't actually implement it. Instead, Java implements labelled break and labelled continue statements.[51] 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.[52] Java was not the first language to take this approach—forbidding goto, but providing multi-level breaks— theBLISS programming language (more precisely the BLISS-11 version thereof) preceded it in this respect.[53]
  • 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 inNetBSD code.[48]
  • Popping the stack in languages such asAlgol andPL/I.
  • Specialized scripting languages that operate in a linear manner, such as a dialogue system for video games.[54]

These uses are relatively common in C, but much less common in C++ or other languages with higher-level features.[50] However, throwing and catching an exception inside a function can be extraordinarily inefficient in some languages; a prime example isObjective-C, where a goto is a much faster alternative.[55]

Another use of goto is to modify poorly factoredlegacy code, where avoiding a goto would require extensiverefactoring orcode 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 consideredcode smell,[56] but finds occasional use.

Alternatives

[edit]

Structured programming

[edit]

Thestructured programming movement aimed to eliminate the need for and use of the goto statement by introducingcontrol structures to a language such as:

Selection
Such as the conditional statement (i.e. if-then-else) and theswitch statement
Iteration
Loop statements such as thefor loop,while loop anddo while loop.
Premature exit
terminate execution of control structure or a single iteration
break
iterate
leave
Some languages, e.g.,PL/I, allow naming the control structure.
foo:doi=1to10;ifi=7theniteratefoo;x(i)=3;end;

These new language mechanisms replaced equivalent control flow that previously would have been written using goto. The switch statement replaces the computed goto in which the instruction to jump to is determined dynamically (conditionally).

Under certain conditions, it is possible to eliminate local goto statements of legacy programs by replacing them with multilevel loop exit statements.[57]

Exception handling

[edit]
Further information:Exception handling

In practice, a strict adherence to the basic three-structure template of structured programming yields highly nested code, due to inability to exit a structured unit prematurely, and acombinatorial explosion with quite complex program state data to handle all possible conditions.

Two solutions have been generally adopted: a way to exit a structured unit prematurely, and more generallyexception handling. Both of these goup the structure, returning control to enclosing blocks or functions, but do not jump to arbitrary code locations. These are analogous to the use of a return statement in non-terminal position – not strictly structured, due to early exit, but a mild relaxation of the strictures of structured programming. In C,break andcontinue allow one toterminate a loop orcontinue to the next iteration, without requiring an extra while or if statement. In some languages multi-level breaks are also possible. For handling exceptional situations, specializedexception handling constructs were added, such astry-catch-finally in Java.

The throw-catch exception handling mechanisms can also be easily abused to create non-transparent control structures, just like goto can be abused.[58]

Tail call

[edit]
Main article:Tail call

In a paper delivered to the ACM conference in Seattle in 1977,Guy L. Steele summarized the debate over the goto and structured programming, and observed that procedure calls in the tail position of a procedure can be most optimally treated as a direct transfer of control to the called procedure, typically eliminating unnecessary stack manipulation operations.[59] Since such "tail calls" are very common inLisp, a language where procedure calls are ubiquitous, this form of optimization considerably reduces the cost of a procedure call compared to the goto used in other languages. Steele argued that poorly implemented procedure calls had led to an artificial perception that the goto was cheap compared to the procedure call. Steele further argued that "in general procedure calls may be usefully thought of as goto statements which also pass parameters, and can be uniformly coded asmachine code JUMP instructions", with the machine code stack manipulation instructions "considered an optimization (rather than vice versa!)".[59] Steele cited evidence that well optimized numerical algorithms in Lisp could execute faster than code produced by then-available commercial Fortran compilers because the cost of a procedure call in Lisp was much lower. InScheme, a Lisp dialect developed by Steele withGerald Jay Sussman, tail call optimization is mandatory.[60]

Although Steele's paper did not introduce much that was new to computer science, at least as it was practised at MIT, it brought to light the scope for procedure call optimization, which made the modularity-promoting qualities of procedures into a more credible alternative to the then-common coding habits of large monolithic procedures with complex internal control structures and extensive state data. In particular, the tail call optimizations discussed by Steele turned the procedure into a credible way of implementing iteration through singletail recursion (tail recursion calling the same function). Further, tail call optimization allowsmutual recursion of unbounded depth, assuming tail calls – this allows transfer of control, as infinite-state machines, which otherwise is generally accomplished with goto statements.

Coroutine

[edit]
Main article:Coroutine

Acoroutine is a more radical relaxation of structured programming, allowing not only multiple exit points (as in returns in non-tail position), but also multiple entry points, similar to goto statements. A coroutine is more restricted than goto, as it can onlyresume a currently running coroutine at specified points – continuing after a yield – rather than jumping to an arbitrary point in the code. A limited form of coroutine is agenerator. Even more limited is aclosure – a function which maintains state (viastatic variables), but not execution position. A combination of state variables and structured control, notably an overall switch statement, can allow a function to resume execution at an arbitrary point on subsequent calls, and is a structured alternative to goto in the absence of coroutines. This is a common idiom in C, for example.

Continuation

[edit]
Main article:Continuation

Acontinuation is similar to a goto in that it transfers control from an arbitrary point in the program to a marked point. A continuation is more flexible than goto in that it can transfer control out of the current function, something that a goto cannot do in most structured programming languages. In those language implementations that maintain stack frames for storage of local variables and function arguments, executing a continuation involves adjusting the program'scall stack in addition to a jump. Thelongjmp function of theC programming language is an example of an escape continuation that may be used to escape the current context to a surrounding one. TheCommon Lisp GO operator also has this stack unwinding property, despite the construct beinglexically scoped, as the label to be jumped to can be referenced from aclosure.

InScheme, a continuation can move control from an outer context to an inner one. This enables writing control structures such as coroutines and cooperative multitasking.[60]

See also

[edit]
  • COMEFROM – Programming language control flow statement; opposite of goto
  • GOSUB – Family of programming languagesPages displaying short descriptions of redirect targets
  • Switch statement – Programming statement for branching control based on a value
  • Non-structured programming – Programming paradigm preceding structured programming

Notes

[edit]
  1. ^Watt & Findlay 2004.
  2. ^Kernighan & Ritchie 1988, p. 224, A9.6 Jump Statements.
  3. ^however jumps within a call chain are possible using thesetjmp/longjmp functions
  4. ^Wagner 2021.
  5. ^"GoTo Statement - Visual Basic | Microsoft Learn".Microsoft Learn. 15 September 2021. Retrieved25 September 2023.
  6. ^Gosling et al. (2005) Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement. The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs.
  7. ^abHindle 2004.
  8. ^abNoack et al. 2015.
  9. ^PHP Manual 2021.
  10. ^Galler 1962, pp. 26–28, 197, 211.
  11. ^, which means that the program jumps to label 20, 30 or 40, in case thati is either less than, equal to or greater than zero.
  12. ^Lahey Computer Systems, Inc 2004.
  13. ^Microsoft 2021.
  14. ^Wehr 1997.
  15. ^z/OS 2.5.0 in IBM Documentation 2021.
  16. ^abGCC, the GNU Compiler Collection 2021.
  17. ^Fronczak & Lubbers 1974, p. 226.
  18. ^Van Tassel 2004.
  19. ^Perl syntax manual 2021.
  20. ^goto for Java 2009. sfn error: no target: CITEREFgoto_for_Java2009 (help)
  21. ^Sexton 2012.
  22. ^abDijkstra 1968.
  23. ^GNU Pascal development team 2005, 5.1 Assorted Pascal Programming Tips.
  24. ^Louden & Lambert 2012.
  25. ^"The unbridled use of the goto statement has as an immediate consequence that it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress. ... The 'go to' statement as it stands is just too primitive, it is too much an invitation to make a mess of one's program."
  26. ^Rubin 1987.
  27. ^Dijkstra, Edsger W.On a Somewhat Disappointing Correspondence (EWD-1009)(PDF). E.W. Dijkstra Archive. Center for American History,University of Texas at Austin. (transcription) (May, 1987)
  28. ^Knuth 1974.
  29. ^Kernighan & Ritchie 1988, pp. 65–66, 3.8 Goto and Labels.
  30. ^abcVine 2007, p. 262.
  31. ^Geisler 2011.
  32. ^Prata 2013.
  33. ^abcdSahni & Cmelik 1995.
  34. ^abcAndrews 2003.
  35. ^McConnell 2004.
  36. ^Regehr 2013.
  37. ^Roberts 1995.
  38. ^Meyer 2009.
  39. ^Kozen & Tseng 2008.
  40. ^Stack Overflow Questions 2012.
  41. ^Pitchford & Tapp 2013.
  42. ^Williams 2013.
  43. ^ANSI X3.9-1978. American National Standard – Programming Language FORTRAN. American National Standards Institute. Also known as ISO 1539-1980, informally known as FORTRAN 77
  44. ^ISO/IEC 1539-1:1997. Information technology – Programming languages – Fortran – Part 1: Base language. Informally known as Fortran 95. There are a further two parts to this standard. Part 1 has been formally adopted by ANSI.
  45. ^Barnes 2006.
  46. ^Summit 1995.
  47. ^abTorvalds 2016.
  48. ^abSpinellis 2003.
  49. ^abCozens 2004.
  50. ^abAllain 2019.
  51. ^Java Tutorial 2012.
  52. ^Gosling & McGilton 1996.
  53. ^Brender 2002, pp. 960–965.
  54. ^Hoad, Nathan (28 July 2022)."nathanhoad/godot_dialogue_manager".GitHub. Retrieved3 February 2023.
  55. ^Chisnall 2012.
  56. ^Contieri 2021.
  57. ^Ramshaw 1988.
  58. ^Siedersleben 2006.
  59. ^abSteele 1977.
  60. ^abKelsey, Clinger & Rees 1998.

References

[edit]
  • Fronczak, Edward J.; Lubbers, Clark E. (September 1974).MTS, Michigan Terminal System. University of Michigan Computing Center. UOM:39015034770076.
  • Geisler, Sandra (2011).C All-in-One Desk Reference For Dummies. John Wiley & Sons. pp. 217–220.ISBN 978-1-118-05424-6.
  • Hindle, Richie (April 1, 2004)."goto for Python".Entrian Solutions. Hertford, UK: Entrian Solutions Ltd. Retrieved2021-11-10.
  • McConnell, Steve (December 2004).Code Complete: A Practical Handbook of Software Construction, Second Edition (2nd ed.). Microsoft Press.ISBN 978-0735619678.
  • Meyer, Bertrand (2009).Touch of Class: Learning to Program Well with Objects and Contracts. Springer Science & Business Media. p. 189.ISBN 978-3-540-92144-8.
  • Perl syntax manual (2021).Goto (Report). Retrieved2021-11-14.
  • PHP Manual (2021)."goto". PHP. Retrieved2021-11-13.
  • Vine, Michael A. (2007).C Programming for the Absolute Beginner. Cengage Learning.ISBN 978-1-59863-634-5.
  • z/OS 2.5.0 in IBM Documentation (2021)."Computed goto statement (IBM extension)". IBM. Retrieved2021-11-13.This document describes the syntax, semantics, and IBM z/OS XL C/C++ implementation of the C and C++ programming languages. For a general-purpose C or C++ standard reference, see cppreference.com.{{cite web}}: CS1 maint: numeric names: authors list (link)
Retrieved from "https://en.wikipedia.org/w/index.php?title=Goto&oldid=1333656164"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2026 Movatter.jp