A self-defining structure or union contains information about its own fields, such as the length of a string. A based structure or union can be declared to manipulate this data. String lengths, array bounds, and area sizes can all be defined by variables, known as the refer object, declared within the structure or union. When the structure or union is allocated (by either an ALLOCATE statement or a LOCATE statement), the value of an expression is assigned to the refer object variable. For any other reference to the structure or union, the value of the refer object is used.
The REFER option is used in the declaration of a based structure or union to specify that, on allocation of the structure or union, the value of an expression is assigned to the refer object and represents the length, bound, or size of another variable in the structure or union. The syntax for a length, bound, or size with a REFER option is shown in the following diagram.
|
Subsequent references to the structure or union obtain the REFER option member’s length, bound, or size from the current value of member-variable (refer object).
In the following example, the declaration specifies that the based structure STR consists of an array Y and an element X.
declare 1 STR based(P),
2 X fixed binary(31,0),
2 Y (L refer (X)),
L fixed binary(31,0) init(1000);
When STR is allocated, the upper bound is set to the current value of L which is assigned to X. For any other reference to Y, such as a READ statement that sets P, the bound value is taken from X.
If the INITIAL attribute is specified for the member with the REFER option, initialization of the member occurs after the refer object has been assigned its value.
Any number of REFER options can be used in the declaration of a structure or union.
The value of the refer object should not be changed during program execution. It is an error to free such an aggregate if the value of the refer object has changed.
Note also that any variables used in the expression defining the REFER extent should be declared in the block (or one of its parent blocks) containing the DECLARE using that REFER. If one of the variables is not declared, it will be implicitly declared following the usual rules for implicit declaration, i.e. a DECLARE for it will be added to the outermost block containing the DECLARE.
This means that in the following code, the declaration of and assignment to the variable m in the subroutine inner_proc will have no effect on the ALLOCATE statement: the ALLOCATE statement will use the implicitly declared and uninitialized m from the main block!
refertst: proc options(main);
dcl
1 a based,
2 n fixed bin(31),
2 c char(m refer(n));
call inner_proc;
inner_proc: proc;
dcl m fixed bin(31);
dcl p pointer;
m = 15;
allocate a set(p);
end;
end;