Skip to content

Gosub_Return Command

Obsolete

The Gosub_Return command is obsolete and was used in procedural code prior to object-oriented DataFlex versions (OOP DataFlex was released in version 3.0 in 1991). You should use Classes and Objects that use Procedures and Functions instead of subroutines.

Purpose

To specify where execution should continue after execution of a subroutine. Use this command instead of the Return command.

Syntax

Gosub_Return [Return] [{label}]

What It Does

  • Used with no argument at the end of a labelled subroutine, Gosub_Return moves execution back to the first command following the gosub or on gosub command that executed the subroutine.

  • Used with a {label} argument at the end of a labelled subroutine, Gosub_Return moves execution to the location of a label in the program. Used with an argument of Return, the Gosub_Return command moves execution to the first command following the gosub or on gosub command that executed the subroutine which contained the gosub or on gosub command that executed the subroutine.

The Stack

Whenever a gosub is done, the line number of the command after the gosub is "pushed" onto a "stack." A stack is a last-in-first-out method of storing return addresses. Whenever a Gosub_Return is done, that address is "popped" from this stack and execution continues at that address. There may be up to 20 return values on the stack at any one time. If you do a gosub to a subroutine and then fail to return from it (i.e., by doing a goto somewhere else in the program), you will accumulate values on the gosub stack. This will eventually result in an Error 97 (Too many GOSUBs without RETURN). Therefore, be sure to return from a subroutine; do not goto out of it!

Example 1

gosub delivery
chain invoice
delivery:
    showln "We're On Our Way!"
    increment sales
Gosub_Return

In this example, the gosub command sends execution to the labelled subroutine delivery. When delivery has executed (increment), the Gosub_Return command moves execution to the next command after the gosub (chain).

Example 2

gosub delivery
chain invoice
cancel:
    move (sales 1) to sales
    abort
delivery:
    showln "We're On Our Way!"
    increment sales
    if customers eq 0 Gosub_Return cancel
Gosub_Return

In this example, the gosub command sends execution to the labelled subroutine delivery. When delivery has executed (increment), the conditional (if) Gosub_Return command moves execution to label cancel if the value of variable customers is zero. If the value of customers is not zero, execution returns to the first command after the gosub (chain).

Important Note

When you execute a gosub from within a subroutine, you must not return to a label that is outside the original subroutine (below its return command). This is because the original gosub command places an address on the return address stack when it executes, and the second gosub command places a second address on the stack. If the Gosub_Return from the secondary subroutine does not return to a point inside the primary subroutine, the address left by execution of the primary subroutine is never cleared. If this is done repeatedly, addresses from the primary subroutine eventually accumulate to fill the stack, and a DataFlex Error 97 (Too many GOSUBs without RETURN) is triggered at runtime. The compiler cannot detect this condition and will not report it at compile time.