SUBROUTINE-ENDSUBROUTINE
WSupported on Windows
|
USupported on Unix
|
VSupported on OpenVMS
|
NSupported in Synergy .NET
|
[access] [subroutine_mod ...] SUBROUTINE name[, option, ...] parameter_def . . . [ENDSUBROUTINE|END]
Arguments
access
(optional) One of the following access modifiers:
Access is not restricted. This is the most accessible option.
Access is limited to the containing class or types derived from the containing class.
Access is limited to the containing type. This is the least accessible option. (default)
Access is limited to the current assembly. (Synergy .NET only)
Access is limited to the current assembly and types derived from the containing class. (Synergy .NET only)
subroutine_mod
(optional) One or more of the following modifiers (Synergy .NET only):
Accessed without a reference object. The method can be executed even if the class that contains the method hasn’t been instantiated.
More than the declared number of arguments can be passed to this routine.
name
The name of the external subroutine to define.
option
(optional) One or more of the following modifiers:
Keep record contents constant for as long as the routine is activated at one or more levels.
Make record contents unique for every activation of the routine.
Keep record contents constant throughout every activation of the subroutine.
Allow multiple active instances of the subroutine.
Keep the routine in memory, even when not in use. (Windows, Unix only)
Use rounding rules for implied-decimal data types within the subroutine.
Use truncation rules for implied-decimal data types within the subroutine. (traditional Synergy only)
More than the declared number of arguments can be passed to this routine.
parameter_def
Subroutine parameter definition. See Defining a parameter.
Discussion
The SUBROUTINE statement identifies the beginning of an external subroutine.
Subroutine names of longer than 30 characters are truncated when the routine is linked (although you can specify up to 255 characters as long as the first 30 characters are unique).
The compiler performs a page feed when the SUBROUTINE statement is encountered.
The LOCAL, STACK, and STATIC modifiers specify the default state of an unqualified RECORD statement. For example, given the following statement:
subroutine fred, STACK
all unqualified RECORD statements in function fred are treated as if they are STACK RECORD statements. LOCAL, STACK, and STATIC are mutually exclusive. If you don’t specify one, the default is LOCAL in traditional Synergy (unless the REENTRANT option is specified) and STACK in Synergy .NET. If REENTRANT is specified, unqualified RECORD statements default to STACK data, rather than LOCAL data, for each instance of the function. For example, given the following statement:
subroutine fred, REENTRANT
all of the unqualified RECORD statements in subroutine fred are treated as if they are STACK RECORD statements.
For information about the precedence of storage qualifiers (LOCAL, STACK, STATIC, and REENTRANT) in the SUBROUTINE statement with those specified in the RECORD statement or on the compiler command line (-qlocal, -qstack, and -qstatic), see the Discussion for RECORD-ENDRECORD.
In Synergy .NET, all routine stack data is refreshed on entry, as if REENTRANT were specified.
The REENTRANT modifier causes all local records to be stack records unless otherwise qualified. Fields in stack records do not allow default or explicit initial values. |
By default, an external subroutine cannot call itself; if it does, the runtime generates a “Recursive XCALL” error ($ERR_RECEXTCAL). However, specifying the REENTRANT modifier on the SUBROUTINE statement enables you to call an external subroutine recursively. (In other words, the subroutine can call itself.)
Object handles are not allowed in local records in REENTRANT routines. |
On Windows and Unix, by default, a subroutine may be removed from memory when it is no longer in the calling chain. If you specify the RESIDENT modifier, the routine stays in memory.
VARARGS is optional for unprototyped subroutines and functions, but if you want to pass more arguments than declared, it is required when using -qnet or strong prototypes (or internal routine prototyping unless -qrelaxed:param is set).
A program by default rounds all expression results. You can change the default to truncate in traditional Synergy by setting system option #11. However, specifying the ROUND or TRUNCATE modifier on a SUBROUTINE statement overrides the default rounding behavior for that routine (including if system option #11 is set). You cannot specify both TRUNCATE and ROUND in the same statement. (Neither TRUNCATE nor system option #11 are supported in Synergy .NET.)
A subroutine can be declared either inside or outside of a namespace or class. A subroutine declared outside of a class is considered to be a global subroutine. In Synergy .NET, when the compiler generates the .exe or .dll file, it puts any global subroutines in a new global class called _CL. If a subroutine is also declared outside of a namespace, it is placed in _NS_assemblyname._CL.
See also