Declaration context
A variable can be declared in different contexts, which defines its visibility.
The DEFINE
statement declares the identifier
of one or more variables, that will be visible to other program blocks depending on the declaration
context of the variables. The scope of reference of a variable defines where it can be referenced in
the program. Depending on the location of the variable definition, memory will be allocated when the
program starts, or during the program execution.
The context of a variable declaration in the source module determines where a variable can be referenced by other language statements, and when storage is allocated for the variable in memory.
- global variables (
DEFINE
inGLOBALS
block) - module variables (
DEFINE
at module level) - local variables (
DEFINE
inFUNCTION
block)
The DEFINE
statement can appear in three contexts:
- Within a
FUNCTION
,MAIN
, orREPORT
program block,DEFINE
declares local variables, and causes memory to be allocated on the runtime stack when the function is called. TheseDEFINE
declarations of local variables must precede any procedural statements within the same program block. The scope of reference of a local variable is restricted to the same program block. The variable is not visible elsewhere. Functions can be called recursively, and each recursive entry creates its own set of local variables. The variable is unique to that invocation of its program block. Each time the block is entered, a new copy of the variable is created. - Outside any
FUNCTION
,REPORT
, orMAIN
program block, theDEFINE
statement declares module variables. Module variables have a persistent state during program execution. Memory for module variables is allocated when the module is loaded. Module variable declarations (DEFINE
) must appear before any program blocks. By default, the scope of reference is the whole module (module variables are private to the module), but it can be extended to the whole program when the variable is declared with thePUBLIC
qualifier. - Inside a
GLOBALS
block, theDEFINE
statement declares global variables that are visible to the whole program. Global variables have a persistent state during program execution. Memory for global variables is allocated when the program starts. MultipleGLOBALS
blocks can be defined for a given module. Use one module to declare all global variables and reference that module within other modules by using theGLOBALS "filename.4gl"
statement as the first statement in the module, outside any program block.
A compile-time error occurs if you declare the same name for two variables that have the same scope. You can, however, declare the same name for variables that differ in their scope. For example, you can use the same identifier to reference different local variables in different program blocks.
You can also declare the same name for two or more variables whose scopes of reference are different but overlapping. Within their intersection, the compiler interprets the identifier as referencing the variable whose scope is smaller, and therefore the variable whose scope is a superset of the other is not visible.
DEFINE myvar INT -- Module variable
MAIN
LET myvar = 0 -- Module variable
DISPLAY "main: myvar=", myvar
CALL func()
DISPLAY "main: myvar=", myvar
END MAIN
FUNCTION func()
DEFINE myvar INT -- Local variable
LET myvar = 1
DISPLAY "func: myvar=", myvar
END FUNCTION
GLOBALS
DEFINE myvar TEXT -- Hidden by module variable
END GLOBALS
DEFINE myvar INT -- Module variable
MAIN
LET myvar = 0 -- Module variable
DISPLAY "main: myvar=", myvar
END MAIN
If a variable needs to be persistent during program execution, instead of using global
variables, consider defining that variable in the module it belongs to, by specifying
the PUBLIC
or PRIVATE
modifiers, depending on the
scope you want to give to your variable, for other modules.