Using Gotos

Using Gotos
Table of Contents

You can use a goto in your ooeu programs by defining goto labels using a colon. A goto label can be any valid Euphoria expression. A constant or variable must be defined before the label is declared. You can, however forward reference a goto label (i.e., you can jump forward as well as backward--see below for exceptions to this). Goto labels have only local (i.e., within one file) and private (i.e., within one routine) scoping, based on whether they occur inside a routine or as top-level code. They cannot be global, and they cannot jump into or out of a routine. There is no checking for jumping into loops, though jumping into for loops is considered undefined, and should not be attempted. While loops should pose no special problems, since there is no special loop variable defined in a while loop. Jumping out of a loop should cause no problems.

Care should be taken if you define a goto label as as variable. A literal or constant-defined label will take precedence over a variable-defined label. You cannot define multiple labels within the same scope with the same value (or with the same variable, though it won't cause an error if a variable later takes on the same value as another label). If multiple variable-defined labels have variables with the same value, then the label that is declared earlier in the program will be the target.

Labels are defined by using a colon (':') followed by the value (or a constant or variable). If the label is a word, it must be enclosed in quotes. A sequence (created using braces) can be used, but if there is anything other than literals delimited by commas, the label is treated like a variable, since it must be evaluated at run time, not compile time. You cannot have a label as the first statement after a function declaration, because it will be interpreted as a return type.

    -- Illegal:
    function foo( integer bar )
        return bar + 1
    end function

    -- Legal:
    function foo( integer bar )
        integer x
        x = bar + 1
    end function
Expressions are allowed (i.e., function calls, arithmetic, sequence concatenation, etc) when defining labels. They will be reevaluated each time program execution happens across them. For instance, if you had an expression as a label at the top of a procedure, each time the procedure is called, the label will be reevaluated. It is faster to assign this result to a constant or other variable before making it a label. Also, by assigning the label value to a variable or constant, you can still forward reference the label.
	object labelA
	procedure foo()
		goto "Label B"
		goto "Label A"
		-- This label is known as soon as labelA is assigned a value.
		puts(1, "Label A\n")
		:"Label " & "B"
		-- This label isn't known until it is executed in normal program flow
		-- during run-time.  The evaluation must happen each time the procedure
		-- is called.
		puts(1, "label B\n")
	end procedure
	labelA = "Label " & "A"
If a goto target is a literal or a constant assigned a literal, and if a literal target exists (i.e., a target whose value is known at compile time), then the goto will be optimized so that the label does not need to be looked up at run time.

If a goto jumps past an abort() call or a return statement, you may get false warnings that the statements after the abort() or return will not be executed.

The following demonstrates legal (though not necessarily recommended) uses of goto:

  : "start"
  printf(1, ": \"%s\"\n", {"start"} )
  goto "spaghetti"

  printf(1, ": %d\n", 1 )
  constant sequence_label = {1,{2}}
  goto {1,{2}}

  object label

  : label
  printf( 1, ": %d\n", label )
  label = "end"
  goto label

  : "spaghetti"
  printf( 1, ": \"%s\"\n", {"spaghetti"})
  label = 5
  goto 4 + 1

  : "end"
  printf(1,": \"%s\"\n",{"end"})
  goto 1

  : sequence_label
  puts(1, ": " ) print(1, {1,{2}}) puts(1,"\n")

  • proc default_goto( object label )   
  • keyword goto   
  • func is_goto( object label )   
  • keyword strict_goto     
    Parent Topics:
  • RDS Incompatible Features

    Using Gotos
    Table of Contents

    ( object label )

    Category: Using Gotos

    This sets a default label to use if the supplied label does not match a valid target. If the default label is itself not a valid target, then the goto is resolved based on the status of the strict_goto directive. The scope of default gotos is confined to routines and files just like other labels.

    See Also: goto, is_goto, strict_goto

    Using Gotos
    Table of Contents


    Category: Using Gotos

    The syntax for using a goto is:

         goto <target> 
    target can be any valid Euphoria expression.

    See Also: default_goto, is_goto, strict_goto

    Using Gotos
    Table of Contents

    ( object label )

    Category: Using Gotos

    This function returns 1 if the specified label is a valid goto target, or zero if it is not.

    See Also: default_goto, goto, strict_goto

    Using Gotos
    Table of Contents


    Category: Using Gotos

    This keyword is meant to be used with "with/without". The default is for strict_goto to be off. This means that if goto is called with a non-existent label, execution will continue with the next statement. In code with strict_goto turned on, an invalid goto target will result in an error.

    See Also: default_goto, goto, is_goto