STORAGE CLASS
Storage class of a variable dictates, at what point of time, storage is to be allocated. PL/I has four storage class. It also determines the way in which the address of that variable is obtained. In static storage, the address of an identifier is determined when the program is loaded into main storage for execution. For automatic variable, the address is determined upon entry to a block.
AUTOMATIC
Variables declared as automatic (default), are allocated in Dynamic Storage Area (DSA). Automatic variables are reinitialized at each activation of the block in which they are declared.
Prologue
The allocation of dynamic storage - that is, for variables that have the AUTOMATIC attribute, is performed by a routine called a prologue.
Epilogue
The release of main storage that has been allocated to AUTOMATIC variables is handled by a routine called an epilogue.
STATIC
For static variables, storage is allocated before execution of the program and remains allocated throughout the entire execution of the program. Static variables are established with their respective values at compile time.
Note:-
Initialize variables at the time of declaration, to reduce program overhead, especially for static variables.
BASED
Variables, which are declared as based, address is contained in a pointer variable.
DCL P POINTER; DCL A(100) FIXED DEC(5) BASED(P);
Here based indicates that the address of the A array is determined by the contents of P.
Pointer variable is a special type of variable you can use to locate data, that is to point to data in main storage. Consequently, a pointer variable can be thought of as an address.
Before a reference can be made to a based variable, a value must be given to the pointer associated with it. This can be done in one of the following ways.
Following table describes each in detail.
How the address is placed in a pointer variable | Facilities | Example |
By assignment of the value returned by the addr built-in function | Overlay-defining of identifiers that do not have same base, scale, and precision. | DCL VALUE1 BIT (32) BASED (P); DCL VALUE2 FLOAT(6); P=ADDR(VALUE2); |
By the assignment statement | Saving pointer values for subsequent use by the program |
DCL (P,Q) PTR; P=ADDR(AREA); Q=P; |
By the set option of a read or locate statement | Processing of data records in their buffers rather than in storage work areas |
READ FILE (INPUT) SET(P); LOCATE FILE (OUTPUT) SET(Q); |
By the allocate statement | List processing |
DCL (P,Q) PTR; DCL AREA CHAR(100) BASED(P); ALLOCATE(AREA); ALLOCATE(AREA) SET(Q); |
Based variable is often used for simulate Overlay Defining, eg.
DCL FIELD CHAR(100) VAR; DCL 1 STRUCTURE BASED(ADDR(FIELD)), 2 LENGTH FIXED BIN(15,0), 2 DATA CHAR(100);
The LENGTH field must be specified in the structure to accommodate the two-byte field that always precedes a variable-length character-string.
Using based variables to Process Data in Buffers
DCL P PTR; DCL 1 IN_REC BASED(P), 2 A PIC'99, 2 B CHAR(10); READ FILE(TAPEIN) SET (P);
The read statement causes a block of data to be read from the file named TAPEIN to an input buffer, and then sets the pointer variable named in the SET option to point to the location in the buffer of the next record. The data in the record can then be processed by reference to the based variable associated with the pointer variable. The record is available only until the execution of the next READ statement that refers to the same file. Thus, the SET option of the READ statement causes the pointer variable P to be set to the starting address of the next record in the internal buffer.
Similarly, when writing from based variables in buffers, the WRITE statement is replaced with the LOCATE statement.
LOCATE OUT FILE (TAPOUT) SET (Q);
By means of the LOCATE statement, the structure of the based variable is superimposed on the data in the output buffer so that any reference to that allocation of the based variable is a reference to the data. The output record area, once located is now available, data may be moved to it via assignment statements.
Example:
COPY: PROC OPTIONS(MAIN); DCL INPUT FILE INPUT RECORD SEQUENTIAL BUFFERED ENV(F BLKSIZE(800) RECSIZE(80) BUFFERS(2)); DCL OUTPUT FILE OUTPUT RECORD SEQUENTIAL BUFFERED ENV(F BLKSIZE (400) RECSIZE(80) BUFFERS(2)); DCL 01 INPUT_REC BASED(P), 02 FIELD1 CHAR(20), 02 FIELD2 CHAR(60); DCL 01 OUTPUT_REC BASED(Q), 02 FIELD1 CHAR(20), 02 FIELD2 CHAR(60); DCL MORE_RECS BIT(1) INIT('1'B); DCL NO BIT(1) INIT('0'B); DCL P PTR; DCL Q PTR; ON ENDFILE(INPUT) MORE_RECS = NO; READ FILE(INPUT) SET (P); DO WHILE(MORE_RECS); LOCATE OUTPUT_REC FILE(OUTPUT) SET(Q); OUTPUT_REC = INPUT_REC; READ FILE(INPUT) SET (P); END; END COPY;
CONTROLLED
Controlled storage is used to create a stack.
The storage for controlled variables is allocated in program by allocate statement and released by the free statement.
DCL A (100) FIXED DEC(5) CONTROLLED; ALLOCATE A; GET LIST(A); TOTAL = SUM(A); FREE A;
Controlled variables can be efficiently used as error handling. During the execution of a program, exceptional conditions, irregularities, or errors in input data are to be noted. Rather than printing out error messages as the errors occur, the messages are to be queued in a stack. Then, at a convenient time, these messages will be printed. The messages could be entered into the stach in the following manner:
DCL MSSG CHAR(100) CONTROLLED; . . IF ERROR THEN DO; ALLOCATE MSSG; MSSG='Appropriate error message here'; END;
For printing message:
PRINT_STACH:PROC; DO WHILE(ALLOCATION(MSSG)>0); PUT SKIP LIST(MSSG); FREE MSSG; END; END PRINT_STACK;