Goto Statement
Branches unconditionally to a specified line within a routine.
To quote the comp.lang.c FAQ:
It has long been observed that unfettered use of goto 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 goto.
Many programmers adopt a moderate stance: goto should usually be avoided, but is 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 is 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.
Situations in which goto is often useful include:
Imposing a self-policed rule that all jumps must be forward (or equivalently all backward, but never mixed) is recommended.
Phix imposes the following limitations on the use of goto statements:
A goto statement must be in the same function as the label it is referring.
The goto statement is not supported in top level code, outside of a routine definition.
There are no computed, assigned, or multiple target forms of the goto statement.
Goto may not be used and labels may not be defined anywhere inside a try/catch statement.
Jumping over variable initialisation will, naturally, leave the variable unassigned.
A goto can optionally refer to
(Technically the colon-less variant is shorthand for the formal with-colon label reference.)
A label, which adheres to the usual identifier rules, is defined by preceding it with a double colon.
Example:
cruelly and relentlessly mocked and ridiculed, unless the programmer is under six years old or recently suffered a stroke.
For hopefully obvious reasons goto rarely makes normal code faster and can actually make things bigger and slower:
Bear in mind that all the optimisations the compiler tries to make are based on standard structured programming constructs, and are disabled as soon as it encounters a low-level statement such as goto or inline assembly. For instance, after
pwa/p2js: JavaScript does not support the goto statement, and therefore neither does the transpiler.
To quote the comp.lang.c FAQ:
It has long been observed that unfettered use of goto 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 goto.
Many programmers adopt a moderate stance: goto should usually be avoided, but is 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 is 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.
Situations in which goto is often useful include:
- To make the code more readable and easier to follow
- To make smaller programs, and get rid of code duplication
- Implementing multi-level break and continue from nested loops and condition.
- Error handling, and particularly cleanup code such as resource deallocation.
Imposing a self-policed rule that all jumps must be forward (or equivalently all backward, but never mixed) is recommended.
Phix imposes the following limitations on the use of goto statements:
A goto statement must be in the same function as the label it is referring.
The goto statement is not supported in top level code, outside of a routine definition.
There are no computed, assigned, or multiple target forms of the goto statement.
Goto may not be used and labels may not be defined anywhere inside a try/catch statement.
Jumping over variable initialisation will, naturally, leave the variable unassigned.
A goto can optionally refer to
label
or :label
- they mean the same thing.(Technically the colon-less variant is shorthand for the formal with-colon label reference.)
A label, which adheres to the usual identifier rules, is defined by preceding it with a double colon.
Example:
procedure p() goto label puts(1,"This will not be printed...\n") ::label puts(1,"...but this will\n") end procedure p()Obviously a more meaningful name than
label
is strongly recommended, and anything like a 1970’s style L01
should be cruelly and relentlessly mocked and ridiculed, unless the programmer is under six years old or recently suffered a stroke.
For hopefully obvious reasons goto rarely makes normal code faster and can actually make things bigger and slower:
if condition then -- faster and smaller goto endif -- ================== else if not condition then statements statements end if end if ::endifBesides, if the compiler did optimise away bizzare constructs such as that "then goto else", as in emit a single jmp instruction instead of the three consecutive jmp asked for, it would probably thwart some forms of trace and trapping in the debugger, or profiling, which might be the very reason for doing it like that in the first place.
Bear in mind that all the optimisations the compiler tries to make are based on standard structured programming constructs, and are disabled as soon as it encounters a low-level statement such as goto or inline assembly. For instance, after
object o = 1
the compiler knows that o is an integer - toss in a goto
and it has to say "right, I have no idea what o might be or even whether or not it is still unassigned".
pwa/p2js: JavaScript does not support the goto statement, and therefore neither does the transpiler.