All LOCAL variables are stored on the stack frame of the Sub/Function/Method/Property in which they are defined. Therefore, the address of local variables may vary with each invocation of the procedure in which they are defined (because they are created each time the procedure is executed, and destroyed upon exit). It is unsafe to return a pointer to a local variable, since the storage for that variable is released when the procedure ends.
Conversely, GLOBAL and STATIC variables are stored in the main data memory area, so their address stays constant for the duration of the program module, so returning a pointer to a GLOBAL or STATIC variable is quite safe.
Typically, the stack frame of a PowerBASIC application can hold close to 1 MB of LOCAL data (also see #STACK). Therefore, care must be exercised when large local ASCIIZ and/or fixed-length strings are used, to ensure that these strings do not exceed the available stack space when the procedure executes. This means that very large ASCIIZ and fixed length strings may need to be changed to a STATIC, GLOBAL, or INSTANCE (for an object) type instead, since those types are not created within the stack frame and will not overflow the stack.
Local dynamic (variable length) strings are not stored in the same manner as ASCIIZ and fixed-length strings. Every dynamic string has an associated 4 byte "string handle", and this handle is stored in the stack frame, but the actual string data is stored in the main data memory area. Therefore, local dynamic strings occupy just 4 bytes of the stack frame regardless of whether the string data itself comprises just one byte or 100 Megabytes.
Similarly, local arrays have an associated "array descriptor" table. This small table is stored in the stack frame, and the actual array data is stored in the main data memory area. Therefore, arrays also have only a very small impact on the stack frame.
It should also be noted that when a DIM statement is used (without an explicit scope clause), to declare a variable (or array) in a procedure, and an identical variable (or array) has already been declared as GLOBAL, the variable in the procedure will be given GLOBAL scope. For example:
GLOBAL xyz AS LONG
...
SUB MySub
DIM xyz AS LONG
' Here, xyz is a GLOBAL variable
END SUB
To ensure that the variable scope is LOCAL to the procedure, use a LOCAL statement rather than a DIM statement. Alternatively, add an explicit scope clause to the DIM statement. For example:
GLOBAL xyz AS LONG
...
SUB MySub
DIM xyz AS LOCAL LONG
' Here, xyz is a LOCAL variable
END SUB
Finally, it should be noted that the DIM statement (without an explicit scope clause) does not affect identically named THREADED variables as is it does with GLOBAL variables. For example:
THREADED abc AS LONG
...
SUB MySub
DIM abc AS LONG
' Here abc is a LOCAL variable, not a THREADED variable
END SUB
See Also