54 of 172
ZBasic Language Reference 47 ZX Microcontroller Family 2.14 Parameter Passing Conventions When a subroutine or function is defined, part of the definition specifies the parameters and their types that are expected by the routine. These parameters are referred to as the “formal parameters”. When a subroutine or function is invoked, parameters must be provided that match the formal parameters in order, number and type. These parameters are referred to as the “actual parameters” for each invocation. As discussed earlier, parameters may be passed to subroutines and functions either “by value” or “by reference”. The differences between these two methods are subtle but important. When passed by value, the actual parameter may be an individual value like a constant or variable or it may be an expression. In either case the value of the actual parameter is calculated and the resulting value is passed to the routine. Within the called routine, the passed value may be utilized in any manner; it may even be modified and this modification will have no effect on any of the constituent elements of the passed parameter value. Effectively, the called routine gets its own private copy of the passed value. When passed by reference, the address of the actual parameter is passed to the called routine. This implies that the actual parameter must be an individual variable or another parameter and not an expression nor a constant. Since the called routine has the address of the actual parameter, it is able to both read from and write to the actual parameter unless otherwise restricted. The ability of a routine to modify a variable passed by reference is often useful, especially in cases where a routine needs to produce multiple values for use by the caller. On the other hand, if used carelessly, it can be the source of errant program operation that is difficult to diagnose. There are restrictions on whether a particular variable type may, may not, or must be passed by value or by reference. For example, a persistent variable cannot be passed by reference because the called routine is expecting the address of a RAM-based variable. Also, for efficiency reasons some variables are always passed to routines by providing the variable address, even if the definition of the routine specifies the parameter is to be passed by value. In such cases, the compiler treats the parameter as being read-only, effectively enforcing the semantics of pass-by-value. Any attempt to modify a read-only variable in the called routine or to pass it by reference to another routine will be detected and reported as an error by the compiler. Arrays may only be passed by reference and then only if they are RAM-based, single-dimension and have a lower bound of 1. Allowed Parameter Passing Methods Actual Parameter Type Pass By Value Pass By Reference Constant or expression, any type Yes No RAM-based variable or array element Yes¹ Yes² RAM-based single-dimension array, 1-based No Yes RAM-based single-dimension array, not 1-based No No RAM-based multi-dimensional array No No Persistent variable or array element Yes No Persistent Memory array No No Program Memory array element Yes No Program Memory array No No Notes: ¹ String types and structures are read-only within the called routine when passed by value. ² The sub-byte types, Bit and Nibble, cannot be passed by reference. Also, in BasicX mode, UnsignedInteger and UnsignedLong types are read-only within the called routine when passed by reference. The table below gives the number of bytes of stack space required to pass different variable types using the two passing methods.