Variable storage and scope

Local (auto) variables

Local variables exist only in the function or macro where they are declared. You cannot simply access a variable declared in one function from another function. You can use the same variable name in different functions but it will not be the same variable.

 

Declaration example:

int i

 

Function parameters also are local variables.

 

Local variables exist only as long as the function is executing. They are automatically created when entering the function and destroyed when leaving the function. Every executing function instance has its own set of local variables.

 

Local variables are located on the stack, in order they were declared. They are aligned on 4 bytes (variables of size 1 to 4 occupy 4 bytes, variables of size 5 to 8 occupy 8 bytes, etc). Variables of composite types (str, BSTR, ARRAY, VARIANT, interface pointers) can also have associated data in dynamic memory. Memory allocation is automatic.

Global (static) variables

Global variables are shared by all functions and macros of current process (QM or exe). Use global variables to share data between different macros or between different instances of the same macro.

 

To declare a global variable, use "+" like in this example:

int+ g_Variable

 

Global variables are created when compiling the function or macro where they are declared, and destroyed when closing QM file, eg when QM exits.

 

The same global variable can be declared multiple times and in multiple places. If you assign a value in the declaration statement (eg int+ g_v1=1), the assignment is performed each time.

 

Don't use global variables where not necessary. Where possible, use local variables, thread variables, pass variables to functions as arguments.

 

To avoid confusion and conflicts when using multiple global variables, use descriptive names with some name convention, for example add "g_" prefix. To reduce the number of global variables, use user-defined types to store several related variables in a single variable

 

If a global variable can be accessed by multiple threads simultaneously, use lock to prevent it, because it is dangerous, may give incorrect results, corrupt memory, make QM unstable.

 

If a macro runs in separate process, it has own global variables. Assume you use global variable g_x in 3 macros. Macro A runs in QM, macros B and C run in separate processes. You cannot use g_x to share data between these 3 macros, because each macro has its own instance of g_x. To share data between these macros you can use registry or a file. Programmers can use Windows API functions, for example shared memory. QM has class __SharedMemory to make it simpler.

Thread variables

Thread scope is intermediate between local and global. Thread variables are shared between all functions of the same thread (running macro). They must be declared in each function where used.

 

To declare a thread variable, use "-" like in this example:

int- t_i

 

Thread variables are created at run time, at the beginning of the function where first time declared in the thread. They are destroyed when the thread exits (macro ends).

 

If you assign a value in the declaration statement, the assignment is performed only the first time during thread execution (differently than local and global variables). Example:

 

int- t_i=5 ;;even if this line is encountered sevel times during thread execution, 5 is assigned only the first time

 

See also: thread variables in special threads

 

Private thread variables

Variables declared with "--" are thread variables that are visible only in that function.

 

Declaration example:

int-- t_i

Member variables and functions

Class members can be used in all member functions of that class. Instead of variable.member use just member or this.member.

Sub-function parent variables

Sub-functions with v attribute can use local variables of parent.

Application variables (obsolete)

Local variables of the main function of a folder that has "Application" property are also visible in other functions of that app folder.

Scope priority

If there are two or more visible variables or functions with the same name and different scope, QM uses the one that is the first in this list:

  1. Predefined (QM language keywords, intrinsic functions, special variables/constants, intrinsic types, other QM-defined types). You cannot declare a variable (except class/type member) with the same name as one of predefined names.
  2. Local and thread variables.
  3. In class member functions - members (variables and functions) of this class, then of base classes.
  4. In sub-functions with v attribute - parent's local variables.
  5. Application main function's variables (obsolete).
  6. Global functions, variables, types, etc.

In class member functions:

 


See also: more types of storage, predefined variables