Based Variables

The BASED attribute defines a template for storage that will be accessed through the use of a locator. A based variable differs from all other variables in the sense that it is a description of storage, but does not have storage of its own. Since it has no storage, it has no address. For example:

DECLARE X CHARACTER(30) BASED; 
DECLARE P POINTER;
   .
   .
   .
P->X = 'ABC';

In this example, assume that an address or pointer value has been assigned to P. The reference P–>X is called a pointer qualified reference, and it enables assignment to the storage addressed by P as if that storage contained a character-string variable like X.

A pointer value can be obtained in two primary ways: from the address of a variable's storage as calculated and returned by the ADDR built-in function, or from the address of storage obtained dynamically by the ALLOCATE statement. For example:

DECLARE K FIXED BINARY(15); 
DECLARE X(5) FLOAT BINARY; 
DECLARE Y FLOAT BINARY BASED; 
DECLARE P POINTER;
   .
   .
   .
P = ADDR(X(K));
P->Y = 10;

In this example, P is assigned the address of X (K) , which is returned by the ADDR built-in function. The second assignment places the value 10 in the storage location given by P in a manner prescribed by the template Y, effectively assigning 10 to X (K) .

A third way to obtain a pointer value is with the POINTER built-in function, which may be used to convert an area offset value to a pointer.

The indiscriminate use of pointers to access the storage of other variables should be discouraged because of the possibilities of unexpected assignment side effects and because the excessive use of pointers makes a program hard to read. Please also note that no checking is performed to ensure that the based variable provides a data description compatible with the declaration of the reference storage. For instance, the statement P–>Y = 10 might produce undesirable results if Y were declared as a data type incompatible with the data type of elements in X. For a discussion of storage sharing using based variables, see the section Storage Sharing.

The ALLOCATE statement uses a based variable to allocate a block of storage that can later be accessed by a based variable together with the locator returned by the ALLOCATE statement. For example:

DECLARE P POINTER;
DECLARE X(C,N) CHAR BASED(P);
N = 10; 
C = 10;
ALLOCATE X SET(P);
   .
   .
   .
P -> X(10,5) = 'A';

In the preceding example, the ALLOCATE statement allocates a storage block of sufficient size to hold a two-dimensional array of 100 one-byte character values and assigns a pointer to that block of storage to P . P–>X thereafter is a reference to that block of storage as an array of 100 one-byte character values.

Based variables can be subscripted just like any other variable. Referring again to the previous example, the statement P–> X (10,5) = ' A' assigns the character 'A' to the element in row 10 and column 5 of the array qualified by P. Since the pointer variable may also be an array, it too can be subscripted. For example:

DECLARE P(3) POINTER; 
DECLARE X(10) FLOAT BASED;
   .
   .
   .
ALLOCATE X SET(P(K));

In the preceding example, P (K)–>X refers to the entire array of ten floating-point elements qualified by the Kth pointer element of P. Likewise, P (K) –>X (J) refers to the Jth element of the floating-point array qualified by the Kth element of pointer array P.

The ALLOCATE statement is the only context in which a based variable can be used without an explicit or implicit locator qualifier. In this context, the based variable is used to describe how much storage is to be allocated.

Implicit locator qualification is a shorthand notation that can be used in cases where many of the references to a based variable use the same pointer. For example:

DECLARE X(10) FLOAT BASED(P); 
DECLARE P POINTER;
   .
   .
   .
ALLOCATE X SET(P);

Because X was declared to be based on P in the previous example, unqualified references to X such as X (K) , X (5), or X are implicitly qualified by P and are equivalent to P–>X (K) , P–>X (5) , and P–>X. Any explicit qualification, such as Q–>X, may be used to temporarily override the implicit qualification and is unaffected by the specification of P in BASED (P) .

The extents of a based variable may be specified as integer valued expressions. The extents are evaluated for each allocation of the variable and for each reference of the variable. The extents are not captured when storage is allocated by an ALLOCATE statement. The extent expression can reference variables declared in the same block, as long as those variables have a value before the based variable is referenced. Changing the value of a variable referenced by an extent expression changes the extent of the based variable. For example:

DECLARE X(N) CHARACTER(1) BASED;

N = 10;
ALLOCATE X SET(P);
   .
   .
   .
N = M;
P->X(5) = 'A';

In this example, the ALLOCATE statement allocates an array of ten elements. The value of M must be greater than or equal to five and less than or equal to ten; otherwise, the reference to P–>x (5) is invalid and may cause unpredictable results.

A block of storage previously allocated by an ALLOCATE statement can be freed by a FREE statement. For example:

FREE P->X;

Once freed, the storage can no longer be accessed, and any attempt to use a pointer such as P that points to the block produces unpredictable results.

Note:

The storage obtained by an ALLOCATE statement is freed only by an explicit FREE. If a program continually allocates memory without freeing it, the program may run out of space at run-time.

Used with the ALLOCATE statement, based variables are powerful tools for applications in which the size of arrays or strings is not known at block entry and must be determined at run-time. Based variable allocations also supply a means for the dynamic creation of graph structure nodes (which may be linked by pointers to produce list and tree structures). See the example of a based structure in the section Block Activation and Recursion.

It is desirable to restrict the extent of based variables to constant values whenever possible to avoid unexpected side effects and to improve program readability. If the extent must be variable, it is preferable to avoid the use of extent expressions when declaring based variables for the same reasons. The size of the based variable is evaluated for each reference to the variable.