The STATIC attribute specifies the way that PL/I is to allocate storage for a variable. The format of the STATIC attribute is:
The STATIC attribute is implied by the EXTERNAL attribute. For more information on STATIC and on other storage-class attributes, see Chapter 5.
The STATIC attribute directly conflicts with the BASED, CONTROLLED,
DEFINED, and parameter attributes. The STATIC attribute cannot be
applied to members of structures, parameters, or descriptions in an
ENTRY or RETURNS attribute.
2.2.50 STREAM Attribute
The STREAM file description attribute indicates that the file consists of ASCII characters and that it will be processed using GET and PUT statements. The format of the STREAM attribute is:
The STREAM attribute is implied by the PRINT attribute. It is also supplied by default for a file that is implicitly opened with a GET or PUT statement.
Specify the STREAM attribute in a DECLARE statement for a file identifier or in the OPEN statement that opens the file.
The STREAM attribute directly conflicts with the RECORD, KEYED, DIRECT,
SEQUENTIAL, and UPDATE attributes.
2.2.51 STRUCTURE Attribute
You can optionally specify the STRUCTURE attribute in the declaration of a structure. The format of the STRUCTURE attribute is:
2.2.52 TYPE Attribute
The TYPE attribute copies the declarations contained within the type declaration to the variable to which it is applied. The format of the TYPE attribute is:
level-number identifier [attributes] TYPE reference
level-numberThe level number to which the declarations in the reference are copied.
identifierThe variable to which the declarations in the reference are to be copied. The identifier must be preceded by a level number.
attributesStorage class or dimensions appropriate for the level number. You can specify a storage class and dimensions with a major structure, or you can specify dimensions with a minor structure.
referenceThe name of a type declaration that is known in the current block.
The TYPE attribute causes the declaration of its reference to be copied, but not the name, storage class, or dimensioning (if any) of the reference. The exception to this rule is that the UNION attribute is propagated in a TYPE declaration. While logical structuring is copied, the level numbers themselves are not copied.
You can use the TYPE attribute on a declaration already containing the TYPE attribute.
A TYPE definition cannot be:
DECLARE 1 S11, 2 F1 CHARACTER(10), 2 F2 TYPE(S11); /* Direct circular */ DECLARE V1 TYPE(V2); /* Indirect circular */ DECLARE V2 TYPE(V3); DECLARE V3 TYPE(V1); DECLARE A1(10) TYPE(A2); /* Indirect circular */ DECLARE A2(10) TYPE(A3); DECLARE A3(10) TYPE(A1); DECLARE 1 S31, 2 F1 CHARACTER(10), 2 F2 TYPE(S32); /* Indirect circular */ DECLARE 1 S32, 2 F1 CHARACTER(10), 2 F2 TYPE(S33); DECLARE 1 S33, 2 F1 CHARACTER(10), 2 F2 TYPE(S31);
DECLARE N FIXED BINARY; DECLARE 1 VARIABLE_X BASED, 2 SIZE FIXED BINARY(15), 2 ITEMS (N REFER (VARIABLE_X.SIZE)) CHARACTER(80); DECLARE VARIABLE_Y TYPE (VARIABLE_X); /* Error - VARIABLE_Y not BASED */
The TRUNCATE attribute is used in the declaration of a formal parameter to indicate that the actual parameter list can be truncated at the point where this argument should occur. The format of the TRUNCATE attribute is:
When the actual call is made, the actual parameter list can stop at the parameter before the one declared with the TRUNCATE attribute. It is possible to pass an actual parameter in a position with the TRUNCATE attribute. Note that in this case, all remaining parameters must also be specified unless they have the TRUNCATE attribute.
A subtle difference between trailing formal parameters for which the TRUNCATE attribute is specified and trailing formal parameters for which the OPTIONAL attribute is specified is that when no actual parameters are specified, the compiler will automatically fill out the minimum argument vector length requires (such as by certain VMS system services) in the OPTIONAL case, but not if only TRUNCATE is specified.
DCL E ENTRY (FIXED,FIXED TRUNCATE,FIXED); CALL E(1); CALL E(1,2,3);
The following call, however, will be invalid:
This call is invalid because the second parameter has the TRUNCATE
attribute, so the third parameter must be specified.
2.2.54 UNALIGNED Attribute
The UNALIGNED attribute is used in conjunction with the BIT attribute to specify that a bit-string variable should not be aligned on a byte boundary. Because UNALIGNED is the default for bit strings, it need not be specified. The format of the UNALIGNED attribute is:
You can use the UNALIGNED attribute in the declaration of character strings. All character strings are aligned on byte boundaries; therefore, the UNALIGNED attribute has no effect on the actual storage of a character string.
The UNALIGNED attribute conflicts with all data-type attributes other
than BIT and CHARACTER.
2.2.55 UNION Attribute
The UNION attribute, which can be used only in conjunction with a level number in a structure declaration, signifies that all immediate members of the major or minor structure so designated occupy the same storage. Immediate members are those members having a level number 1 higher than the major or minor structure with the UNION attribute. For example, if the UNION attribute were associated with level n, then all members or minor structures at level n+1 up to the next member at level n would be immediate members and would occupy the same storage. The format for the UNION attribute is:
level-number identifier [storage-class] UNION
level-numberThe level number of the variable with which the declarations in the reference share storage.
identifierNames the variable with which the declarations in the reference share storage. A variable declared with the UNION attribute must be a major or minor structure.
storage-classThe storage class specified for the structure. You can specify the storage class only on level 1.
The UPDATE attribute is a file description attribute indicating that the associated file is to be used for both input and output. You can apply the UPDATE attribute to relative files, indexed files, and sequential disk files with fixed-length records. The format of the UPDATE attribute is:
Specify the UPDATE attribute on a DECLARE statement for a file constant or on an OPEN statement to access the file for update. The UPDATE attribute implies the RECORD attribute.
For a description of the attributes that are applied to files, see Section 18.104.22.168.
The UPDATE attribute directly conflicts with the INPUT, OUTPUT, STREAM,
and PRINT attributes and with any data-type attribute other than FILE.
2.2.57 VALUE Attribute
The VALUE attribute is provided for passing parameters by value rather than by reference, or it can be used to specify a global constant value. The format of the VALUE attribute is:
The VALUE attribute serves two purposes:
The compiler will accept a parenthesized program section name following the GLOBALDEF keyword, but that program section name will be ignored.
The VALUE attribute, when specified with the BIT attribute, implies the
2.2.58 VARIABLE Attribute
The VARIABLE attribute indicates that the associated identifier is a variable. VARIABLE is implied by all computational data-type attributes and by all noncomputational attributes except FILE and ENTRY. The format of the VARIABLE attribute is:
If you specify the FILE or ENTRY attribute in a DECLARE statement without the VARIABLE attribute, the defined object is assumed to be a file or entry constant.
The VARIABLE attribute is implied by the LABEL attribute. You can declare label constants only by using the label identifier in the program; you cannot define a label constant in a DECLARE statement.
The VARIABLE attribute is not valid in a returns descriptor or in a
2.2.59 VARYING Attribute
The VARYING attribute indicates that a character-string variable does not have a fixed length, but that its length changes according to its current value. The format of the VARYING attribute is:
You must specify a length attribute in conjunction with VARYING by giving the maximum length allowed for the variable. The current length is stored with the value and can be determined at any time with the LENGTH built-in function. If you need to determine the maximum declared length of a varying- length character string, use the MAXLENGTH built-in function.
The value of an uninitialized CHARACTER VARYING variable is undefined.
Special rules apply to reading and writing record files into and from variables that have the VARYING attribute. See the Kednos PL/I for OpenVMS Systems User Manual.
The VARYING attribute directly conflicts with any data-type attribute other than CHARACTER.
DECLARE STRING CHARACTER(80) VARYING;
A variable named STRING is declared as a varying-length character string with a maximum length of 80 characters.
S: PROCEDURE OPTIONS(MAIN); DECLARE STRING CHARACTER(80) VARYING; STRING = 'PIE'; PUT LIST (LENGTH(STRING)); PUT LIST (MAXLENGTH(STRING)); PUT LIST (SIZE(STRING)); END;
The value returned by the built-in function LENGTH is 3, the length of the current value of the string. The value returned by the built-in function MAXLENGTH is 80, the maximum declared length. The value returned by the built-in function SIZE is 82, the maximum declared length plus two (for the two bytes that hold the value of the current length).
All programs process data items. Data items can be constants or variables. A constant data item has a value that does not change during program execution; a variable data item can represent different values.
A data item has an associated type that you can specify as an attribute or collection of attributes in a declaration. Unlike other languages that often have a distinction between data types and data attributes, a PL/I data type is entirely defined by the data attributes given to a data item identifier. The data type that you select determines the operations that you can perform on data items and how they are stored.
The rest of this chapter describes data types in more detail.
3.1 Summary of Data Types
PL/I supports the following computational data types:
PL/I also supports the following noncomputational data types and attributes:
You can place each of these data types in aggregate structures or
arrays to form new data types. See Chapter 4 for more information.
All names referenced in a PL/I program must be declared explicitly, with the exception of entry-point names, statement labels, built-in functions, and the default file constants SYSIN and SYSPRINT. You declare a name and its data type attributes in a DECLARE statement. For example:
DECLARE AVERAGE FIXED DECIMAL; DECLARE NAME CHARACTER (20);
The keywords DECIMAL, FIXED, and CHARACTER describe characteristics, or
attributes, of the variables AVERAGE and NAME.
3.1.2 Default Attributes
It is not always necessary to define all the characteristics, or attributes, of a variable; the PL/I compiler makes assumptions about attributes that are not explicitly defined. For example:
DECLARE NUMBER FIXED;
The default FIXED attribute implies the attributes BINARY(31,0). Thus, the variable NUMBER has the attributes FIXED BINARY(31,0).
Table 3-1 shows the default attributes implied by each computational data attribute.
Constants have attributes implied by the characters used to specify them. The following list describes the expression of constants and their attributes:
Note that PL/I has no constants with the attributes FIXED BINARY, FLOAT BINARY, or PICTURE. However, this presents no problems in programming because you can assign constants of any computational type to variables of any computational type and they are converted automatically to the target type.
You usually give values to binary variables by assigning decimal constants to them. For example:
I = 1;
F = 1.333E-12;
Picture variables are usually given values by assigning fixed-point decimal constants. For example:
PAY_PIC = 123.44;
The implied data types of constants are important primarily because of PL/I's rules for converting operands in an arithmetic operation. (Bit-string and character-string operations must have bit- and character-string operands, respectively.) All operations, including arithmetic operations, must be performed in a single data type, and automatic conversions are performed on arithmetic operands to make this possible. For example:
DECLARE X FLOAT DECIMAL (49); X = X + 1.3;
In this example, the fixed-point decimal constant 1.3 is converted to floating-point decimal before the addition is performed. The rules for operand conversion are discussed in detail in Section 6.4.2.
For information about arithmetic operators, operands, and data
conversions, see Chapter 6.
3.1.3 Compatible Data Types
In PL/I, the notion of compatible data types is used in the rules for passing arguments by reference and for based, controlled, defined, or external variables. For two nonstructure variables to have compatible data types, the following attributes must agree. That is, if one variable has the attribute, the other variable must also have it after the application of default rules.
Two pictured variables must have identical pictures after the expansion of iteration factors.
In addition, the following values must be equal:
Two structure variables have compatible data types if they have the same number of immediate members, and if corresponding members have compatible data types.
In general, you can specify string lengths, area sizes, and array bounds with expressions or with asterisks. The values used to determine whether two variables have compatible data types are obtained as follows:
Consider the following example:
/* Example of extent determination */ DATAT: PROCEDURE (PTR1); DECLARE N FIXED, S CHARACTER(N) BASED(PTR1); DECLARE PTR1 POINTER; N = 10; CALL P(S); P: PROCEDURE(A); DECLARE A CHARACTER(*), B CHARACTER(N); N = 20; PUT LIST(LENGTH(A),LENGTH(B),LENGTH(S)); END P; END DATAT;
The PUT statement writes out:
10 10 20
The assignment to N inside the procedure P affects the extent of S, but not the extents of A or B, which were frozen when P was invoked.