Storage Classes

It is important to understand PL/I storage classes. Each has its advantages and disadvantages.

STATIC

Static storage is allocated and initialized (if INITIAL attribute applies) at compile time. A large amount of static storage makes the size of the executables larger and can lead to longer load times at run time. Any modification of static storage may leave a program in a differing state to its original, and produce incorrect results on subsequent invocations.

If you do modify static storage, make sure it is left in the same state as it was before program execution began. This is known as serially reusable state, and is particularly important for programs running under Enterprise Server (CICS, IMS, and JCL batch), because the programs are generally kept in storage (not reloaded) to improve system performance. In general, this storage class should be used for all 'read-only' storage; for example:

Dcl report_name char(132) static
init('Year to date Performance Report');

Static storage is freed only when the executable containing it is physically deleted. Depending on the operating system, logically deleted executables may get reused with static storage in its last used state.

AUTOMATIC

Automatic storage is allocated and initialized (if INITIAL attribute applies) at run time upon entry to the block (PROCEDURE or BEGIN) in which it is declared. The allocation scheme is the most efficient of all dynamically allocated storage schemes and costs almost nothing. The initialization is the same as an equivalent assignment made to the subject variable. Any changes to such storage may be left as they are, because upon next entry to the block, this storage will be re-allocated and re-initialized.

Automatic storage is automatically freed upon block exit. Any freed storage (all or some of it) is reused by the allocation of automatic storage upon next invocation of the existing or a different block.

This storage class should be used for all working storage. This storage class is inherently suitable for re-entrant code.

BASED

Based storage is allocated and initialized (if INITIAL attribute applies) by the use of the ALLOCATE statement at run time, and is completely under programmer control. ALLOCATE statements allocate storage on the heap via calls to library routines, and effectively generate assignments for the initialization values. The allocation scheme is costly, but it does give the programmer total control over when storage is allocated and how long it lives for before it is freed. This storage is generally good for allocation of objects that need to exist when the program logic warrants it, or are of large or varying sizes. Any changes to such storage may be left as they are.

Based storage is freed using the FREE statement, and is managed by an address held in a locator variable (generally a POINTER, but also an OFFSET) and may be allocated multiple times using a unique locator for each allocation. Storage may be allocated or freed without any order as long a unique locator is used. This storage class is used to maintain lists of data that dynamically grow and shrink.

This storage class should be used when the existence and lifetime of the storage depends on application processing being carried out. This storage class is also inherently suitable for re-entrant code.

Note: Another way to allocate based storage is by setting the locator to the address of another object using the ADDR or ADDRDATA BUILTIN. When this mechanism is used, storage must not be FREE(d) since it was never ALLOCATE(d).
CONTROLLED

Controlled storage is like based storage; it is allocated using the ALLOCATE statement and freed using the FREE statement, but with these important differences:

  • You do not have a locator. PL/I manages the locator on your behalf.
  • The ALLOCATE statement 'pushes down' the current generation (if any) before allocating the new one.
  • The FREE statement frees the current generation and 'pops up' the previous (if any) generation.
  • Any access to the variable will always access the current generation. Only the current generation is visible. All pushed generations are hidden.
  • This allocation scheme is more costly than based, but potentially has more powerful uses.

This storage class should be used for all storage that must be managed as a push down stack where the most recently allocated generation will be freed first. This storage class is also inherently suitable for re-entrant code.

Parameter
Parameter storage, for completeness, is nothing more than a way to map the parameter on the corresponding argument in the invocation of the procedure containing the parameter.