There are two types of locator data: pointer and offset.
The value of a pointer variable is an address of a location in storage. It can be used to qualify a reference to a variable with allocated storage in several different locations.
The value of an offset variable specifies a location within an area variable and remains valid when the area is assigned to a different part of storage.
A locator value can be assigned only to a locator variable. When an offset value is assigned to an offset variable, the area variables named in the OFFSET attributes are ignored.
Locator data cannot be converted to other data types, except as follows:
When an offset variable is used in a reference, it is implicitly converted to a pointer value by using the address of the area variable designated in the OFFSET attribute and the offset variable. Explicit conversion of an offset to a pointer value is accomplished using the POINTER built-in function. For example, the following statement assigns a pointer value to P, giving the location of a based variable, identified by offset O in area B.
dcl P pointer, O offset(A),B area; P = pointer(O,B);
Because the area variable is different from that associated with the offset variable, you must ensure that the offset value is valid for the different area. It is valid, for example, if area A is assigned to area B prior to the invocation of the function.
The OFFSET built-in function, in contrast to the POINTER built-in function, returns an offset value derived from a given pointer and area. The given pointer value must identify the location of a based variable in the given area.
A pointer value is converted to offset by using the pointer value and the address of the area. This conversion is limited to pointer values that relate to addresses within the area named in the OFFSET attribute.
Except when assigning the NULL or the SYSNULL built-in function value, it is an error to attempt to convert from or to an offset variable that is not associated with an area.
There is no implicit locator conversion in multiple assignments.
A locator reference is either a locator variable that can be qualified or subscripted, or a function reference that returns a locator value.
A locator reference can be used in the following ways:
Because PL/I implicitly converts an offset to a pointer value, offset references can be used interchangeably with pointer references.
Locator qualification is the association of one or more locator references with a based reference to identify a particular generation of a based variable. This is called a locator-qualified reference. The composite symbol -> represents "qualified by" or "points to". The following syntax diagram is for an explicit qualified reference.
In the following example, X is a based variable, P is a locator variable, and Q is a based locator variable.
P -> Q -> X
The reference means that it is that generation of X that is identified by the based locator Q that is also identified by the value of the locator P. X and Q are said to be explicitly locator-qualified.
When more than one locator qualifier is used, they are evaluated from left to right.
Reference to a based variable can also be implicitly qualified. The locator reference used to determine the generation of a based variable that is implicitly qualified is the one declared with the based variable. In the following example, the ALLOCATE statement sets the pointer variable P so that the reference X applies to allocated storage.
dcl X fixed bin based(P) init(0); allocate X; X = X + 1;
The references to X in the assignment statement are implicitly locator-qualified by P. References to X can also be explicitly locator-qualified as shown in the following example.
P->X = P->X + 1;
The following assignment statements have the same effect as the previous example:
Q = P; Q->X = Q->X + 1;
Because the locator declared with a based variable can also be based, a chain of locator qualifiers can be implied. For example, the following pointer and based variables can be used:
declare (P(10),Q) pointer,
R pointer based (Q),
V based (P(3)),
W based (R),
Y based;
allocate R,V,W;
Given the previous declaration and allocation, the following references are valid:
P(3) -> V V Q -> R -> W R -> W W
The first two references are equivalent, and the last three are equivalent. Any reference to Y must include a qualifying locator variable.
A pointer that qualifies a based variable represents one level of locator qualification. An offset represents two levels because it is implicitly qualified within an area. The number of levels is not affected by a locator being subscripted and/or an element of a structure or union. In the following example, the references X, P -> X, and Q -> P -> X represent three levels of locator qualification.
declare X based (P),
P pointer based (Q),
Q offset (A);