# call statement

The call statement transfers control
to an external FlashBASIC or BASIC subroutine and optionally passes
a list of arguments to it.

## Syntax

```
call cataloged.program.name{(arg{,arg...})}
call @ program.name.var{(arg{,arg...})}
call "file.ref program.name"{(arg{,arg...})}
```

## Description

Arguments must be separated
with a comma. When passing arguments, the same number must occur in
the call statement as are declared in the subroutine statement, which must occur as the first executable
line of the external subroutine. There is a maximum of approximately
200 arguments. The subroutine can return values to the calling program
in variable arguments.

The external subroutine must ultimately
execute a return statement to continue program
execution at the statement immediately following the call statement. Subroutines that do not return terminate execution.

Note: **For Windows:**

- Locally defined variables in external subroutines (and files opened to local file variables) are automatically abandoned or closed upon return.

- Use caution when making recursive calls. If the depth of the call is too deep, the thread will be terminated.

The call @, or indirect call form
allows the statement to use the subroutine name assigned to a specific
variable.

Called subroutines must be compiled and cataloged
separately from the calling program. The arguments passed between
(to and from) the program and subroutine are not label-sensitive,
but are order-sensitive. The arguments listed in the subroutine statement and the arguments listed in the call statement can be different. The subroutine receives the results
of arguments in the order in which they are specified in the argument
list.

Variable arguments are passed to the subroutine at call
time and from the subroutine at return time.

Arrays can be passed
between programs and subroutines. The array in the program and called
subroutine must contain the same number of elements. If dimensioned
arrays are used, the arrays should be dimensioned exactly the same
in both the program and subroutine. Alternately, a dim statement can be specified without the actual number of elements.
The array is properly initialized at run time.

Arguments listed
in both the call and subroutine statements should not be duplicated in the argument lists. Arguments
that are also defined as common variables in both calling programs
and subroutine programs should not be used in argument lists because
the data is already accessible through the common allocations. Violation
of these rules can result in unpredictable values being passed between
the programs.

It is possible to specify the file path name followed
by a space followed by the actual subroutine name. To do this, the
file path and program name can be passed via a variable to an indirect
call, or the string can be enclosed in quotation marks and embedded
directly into the program text. Specifying a direct file reference
and program name eliminates the need for cataloging subroutines when
an application is used from other accounts.

On D3 9.0, if the
subroutine is not cataloged, FlashBASIC or BASIC attempts to locate
the subroutine object code in the same dictionary in which the program's
object code resides. This eliminates the need to catalog most subroutines.

Note: The initial overhead for an external subroutine call requires
the program name be found in the master dictionary. This item points
to the object code file. The object pointer is read next and it points
to the actual object code.

Dynamic array elements passed
to subroutines are treated as function results and are therefore not
updated after the call returns.

## Calling BASIC subroutines

When calling a
subroutine from BASIC, a variable is created which is associated to
the name of the subroutine in the object code of the program performing
the call. For improved performance, the location of the subroutine
is stored in the variable so that subsequent calls do not have to
look up the location of the object code. This also occurs using the
format `“*filename* *subname*”(*parameters*)`. However the `@*subname*(*parameters*)` syntax
does not allow for this optimization. The name of the subroutine
is stored in the *subname* variable, rather than
the address of the object code. Because the subroutine name may change
from call to call, the name must be *resolved* every time. As
a result, it may appear that the basic protection functionality is
not properly functioning. For example, a program containing:

```
call sub(x)
call “sub”(x)
mysub = ‘sub’; call @mysub
```
Initially all three lines would
call the same subroutine, however the @*subname* needs
to be looked up each time it is executed, it resolves to the new subroutine
after it is compiled - whereas the other formats would still be pointing
to the old object code (thus the need for the basic protection).

## Calling FlashBASIC subroutines

When calling
subroutines from FlashBASIC, the format of the calls do not affect
performance. However, the name of the subroutine affects how the
program is located in memory. Using the three forms below, and assuming
you are in the myacct account and sub only exists in the bp file,
would load the sub subroutine into memory three times.

```
call sub(x)
call “bp sub”(x)
mysub = ‘myacct,bp, sub’; call @mysub
```
Note: This is not due
to the three different formats, but because the name of the subroutine
is referenced three ways (`sub`, `“bp sub”`, and `‘myacct,bp, sub’`).

Using the forms
below instead would only load the sub subroutine once in memory and
would be located quickly for any of the three different calls. This
means that if sub is recompiled while a process has it loaded in memory,
it will never call the new version until the old one is removed from
memory by going to TCL.

```
call sub(x)
call “sub”(x)
mysub = ‘sub’; call @mysub
```

## Example(s)

Direct call:

```
call process.lines(ID,order.item(1))
```
or

```
call "process.lines"(ID,order.item(1))
```
With or without quotation marks, this example still calls
the `process.lines` subroutine.

Indirect call:

```
program.var = "process.lines"
call @program.var(ID,order.item(1))
```
This example calls the subroutine name held as a string
in the variable `program.var`.

Indirect call
with full path name:

```
program.var = "dm,bp, process.lines"
call @program.var(ID,order.item(1))
```

## See also

- [$chain directive](https://d3codex.com/pickbasic-flashbasic/dollar-chain-directive/)
- [common statement](https://d3codex.com/pickbasic-flashbasic/common-statement/)
- [enter statement](https://d3codex.com/pickbasic-flashbasic/enter-statement/)
- [Compiling programs](https://d3codex.com/pickbasic-flashbasic/compiling-programs/)
- [precision statement](https://d3codex.com/pickbasic-flashbasic/precision-statement/)
- [return statement](https://d3codex.com/pickbasic-flashbasic/return-statement/)
- [Statements and functions](https://d3codex.com/pickbasic-flashbasic/statements-and-functions/)
- [subroutine statement](https://d3codex.com/pickbasic-flashbasic/subroutine-statement/)
- [tcl statement](https://d3codex.com/pickbasic-flashbasic/tcl-statement/)
- [u31a2 user exit](https://d3codex.com/proc/u31a2-user-exit/)

---
Source: https://d3codex.com/pickbasic-flashbasic/call-statement/ - part of the D3Codex reference.
