10 Killer Tips to Write Zo/s PLI program

The following are the top 10 tips to write perfect PLI program.


Source programs may be written in upper or lower case. There is no difference between the cases, except within strings.


Varying strings (declared with the attribute VARYING) are similar to C’s char.

For an exact equivalant, in Enterprise PL/I for z/OS you may use the attribute VARYING, in which strings are zero-terminated.

Without the attribute VARYING, strings are of fixed length. Such strings always store the specified number of characters. Thus,

S = 'abc     ';

Stores eight characters, namely, abc followed by five blanks, whereas

declare V character(8) varying;
V = 'abc     ';

requires a storage of 10 bytes: 2 bytes for the actual length of V and 8 bytes for the characters. This latter feature makes possible the assignment

V = V || 'dog';

which appends the word dog to what is already stored in V (up to a maximum of 8 characters in this example, of course).

Content of V after V = 'abc';:
|   3   | a | b | c | ? | ? | ? | ? | ? |   /* "?" means: value is undefined */
          1   2   3   4   5   6   7   8     /* index of character */
Content of V after V = V || 'dog';:
|   6   | a | b | c | d | o | g | ? | ? |   /* "?" means: value is undefined */
          1   2   3   4   5   6   7   8     /* index of character */
declare i fixed binary;  is equivalent to C’s int;
declare i fixed binary (31); is equivalent to C’s long int.
declare i fixed binary (63); is equivalent to C’s long long int.
Decimal arithmetic, because it is fixed-point, needs some care.

The built-in functions ADD, SUBTRACT, MULTIPLY, and DIVIDE are provided to enable the programmer to specify the precision of each result. Thus they help to avoid overflow. For decimal fixed-point division, it is strongly recommended that the DIVIDE function be used. Thus, to divide A by B, where A has precision (10,5), and B has precision (6), the recommended form is:

declare A fixed decimal (10,5),
B fixed decimal(6),
C fixed decimal (10,5);
A = 12345.67891;
b = 98765;
C = divide(A, B, 10, 5);

In the DIVIDE reference, the arguments 10 and 5 direct that the result A/B has a total of ten digits, with 5 digits after the decimal point, respectively. This value is then stored in C. IBM PL/I permits up to 31 decimal digits for fixed-point working.


When running PL/I programs, use the condition prefixes SIZE, STRINGRANGE, STRINGSIZE, and SUBSCRIPTRANGE, on the initial procedure statement thus:

   trial: procedure options (main);

This enables checking for fixed-point overflow, and range-checking and truncation for strings and for subscripts:

  • The lower bound of arrays is unity by default, not zero.
  • Division of integers (whether decimal or binary or mixed) may produce a fixed-point result having a scale factor. Thus, 9/2 produces 4.5000000, unlike Fortran which produces the integer 4. Should an integer result be required, TRUNC or DIVIDE may be used, thus: TRUNC(9/2) or – more generally – DIVIDE(J, K, 31), the latter giving 31 bits of precision for a binary integer result. Alternatively, declaring binary integer variables to have maximum precision (typically 31 bits) will ensure that the result of dividing two such integer variables will give an integer result.