The declaration of a name in a PL/I program consists of a user-specified identifier and the attributes of the name. The attributes describe the following:
A name is declared either explicitly in a DECLARE statement or implicitly by its appearance in a particular context. For example:
This statement is an implicit declaration of the name CALC as an entry constant.
This chapter describes the DECLARE statement and data attributes.
2.1 DECLARE Statement
The DECLARE statement specifies the attributes associated with names.
The format of the DECLARE statement is:
declarationOne or more declarations consisting of identifiers and attributes. A declaration has the following format:
levelLevels are used to specify the relationship of members of structures; if a level is present in the declaration, it must be written first.
declaration-itemA declaration-item has the following format:
The format of the DECLARE statement varies according to the number and nature of the items being declared. The DECLARE statement can list a single identifier, optionally specifying a level, bound-pair list, and other attributes for that identifier. Alternatively, the statement can include, in parentheses, a list of declarations to which the level and all subsequent attributes apply. The declarations in the second case can be simple identifiers or can include attributes that are specific to individual identifiers.
Bound pairs are used to specify the dimensions of arrays. If bound pairs are present, they must be in parentheses and must immediately follow the identifier or the list of declarations. For example, (2:10), lower bound is 2 and upper bound is 10. Bounds can be any valid PL/I expression.
The various formats are described individually in the following
2.1.1 Simple Declarations
A simple declaration defines a single name and describes its attributes. The format of a simple declaration is:
DECLARE identifier [attribute ...] ;
identifierA user-supplied name, containing a minimum of 1 character. On VAX the maximum number of characters is 31, while on Alpha the maximum number of characters is 64. The name must be unique within the current block.
An identifier can consist of any of the alphanumeric characters A through Z, a through z, 0 through 9, dollar signs ($), and underscores (_), but must begin with an alphabetic letter, dollar sign, or underscore. PL/I converts all lowercase letters to uppercase when it compiles a source program. The identifiers abc, ABC, Abc, and so on all refer to the same object.
attributeOne or more attributes of the name. Attribute keywords must be separated by spaces. They can appear in any order.
See Section 2.2 for a list of the valid attribute keywords and their meanings.
The following are examples of simple declarations:
DECLARE COUNTER FIXED BINARY (7); DECLARE TEXT_STRING CHARACTER (80) VARYING; DECLARE INFILE FILE;
Names that are not given specific attributes in a DECLARE statement or
that are referenced without being declared, receive the default
attributes FIXED BINARY (31,0) AUTOMATIC. Note that the compiler issues
a warning message whenever it gives these default attributes to a name.
2.1.2 Declarations Outside Procedures
You can declare a variable outside any procedure. Any variable so declared will be visible within all procedures contained by the module. The format for declarations outside procedures is the same as for other declarations, except that the storage-class attribute cannot be AUTOMATIC. If a storage-class is not specified or is specified as AUTOMATIC, the compiler will issue a warning and supply the STATIC attribute. The following example shows the use of this type of declaration:
DECLARE A STATIC FIXED BINARY(31); . . . FIRST: PROCEDURE; DECLARE B FIXED BINARY(31); . . . END FIRST; SECOND: PROCEDURE; DECLARE C FIXED BINARY(31); . . . END SECOND;
In this example, variable A is visible in both the FIRST and SECOND
procedures, but variables B and C are visible only in their containing
2.1.3 Multiple Simple Declarations
Multiple simple declarations define two or more names and their individual attributes. This format of the DECLARE statement is:
DECLARE identifier [attribute ...] [,identifier [attribute ...]] ...;
When you specify more than one set of names and their attributes, separate each name and attribute set from the preceding set with a comma. A semicolon must follow the last name.
The following is an example of multiple declarations:
DECLARE COUNTER FIXED BINARY (7), TEXT_STRING CHARACTER (80) VARYING, Y FILE;
This DECLARE statement defines the variables COUNTER, TEXT_STRING, and
Y. The attributes for each variable follow the name of the variable.
2.1.4 Factored Simple Declarations
When two or more names have common attributes, you can combine the declarations into a single, factored declaration. This format of the DECLARE statement is:
DECLARE (identifier[,identifier ...]) [attribute ...];
When you use this format, you must place names that share common attributes within parentheses and separate them with commas. The attributes that follow the parenthetical list of names are applied to all the named identifiers.
The following are examples of factored declarations:
DECLARE (COUNTER, RATE, INDEX) FIXED BINARY (7) INITIAL (0); DECLARE (INPUT_MESSAGE, OUTPUT_MESSAGE, PROMPT) CHARACTER (80) VARYING;
In these declarations, the variables COUNTER, RATE, and INDEX share the attributes FIXED BINARY (7) and are given the initial value of zero. The variables INPUT_MESSAGE, OUTPUT_MESSAGE, and PROMPT share the attributes CHARACTER (80) VARYING.
You can also specify, within the parentheses, attributes that are unique to specific variable names, using the following format:
DECLARE (declaration-item, declaration-item [,declaration-item]) attribute ...
DECLARE (INFILE INPUT RECORD, OUTFILE OUTPUT STREAM) FILE;
The DECLARE statement declares INFILE as a RECORD INPUT file and OUTFILE as an STREAM OUTPUT file.
The parentheses can be nested. For example:
DECLARE ( (INFILE INPUT, OUTFILE OUTPUT) RECORD, SYSFILE STREAM ) FILE;
The DECLARE statement declares INFILE as a RECORD INPUT file, OUTFILE
as a RECORD OUTPUT file, and SYSFILE as a STREAM file.
2.1.5 Array Declarations
The declaration of an array specifies the dimensions of the array and the bounds of each dimension. This format of a DECLARE statement is:
DECLARE declaration (bound-pair,...) [attribute ...];
where each bound pair has the following format:
One bound pair is specified for each dimension of the array. The number of elements per dimension is defined by the bound pair. The extent of an array is the product of the numbers of elements in its dimensions. If the lower bound is omitted, the lower bound for that dimension is 1 by default.
You can use the asterisk (*) as the bound pair when arrays are declared as parameters of a procedure. The asterisk indicates that the parameter can accept array arguments with any number of elements. (If one dimension is specified with an asterisk, all must be specified with asterisks.)
DECLARE SALARIES(100) FIXED DECIMAL(7,2);
DECLARE (SALARIES,PAYMENTS) (100) FIXED DECIMAL(7,2);
For further details on how to specify the bounds of an array, and for
examples of array declarations, see Section 4.1.1.
2.1.6 Structure Declarations
The declaration of a structure defines the organization of the structure and the names of members at each level in the structure. This format of a DECLARE statement is:
Each declaration specifies a member of the structure and must be preceded by a level number. As shown in the following example, a single variable can be declared at a particular level; or the level can contain one or more complete declarations, including declarations of arrays or other structures. The major structure name is declared as structure level 1; minor members must be declared with level numbers greater than 1.
DECLARE 1 PAYROLL, 2 NAME, 3 LAST CHARACTER(80) VARYING, 3 FIRST CHARACTER(80) VARYING, 2 SALARY FIXED DECIMAL(7,2);
This statement declares a structure named PAYROLL.
Alternatively, because the last and first names have the same attributes, the same structure can be declared as follows:
DECLARE 1 PAYROLL, 2 NAME, 3 (LAST,FIRST) CHARACTER(80) VARYING, 2 SALARY FIXED DECIMAL(7,2);
For details and examples of structure declarations, see Section 4.2.1.
Attributes define and describe the characteristics of names used in a PL/I program. Each name in a PL/I program has a set of attributes associated with it. You can specify attributes in any of the following contexts:
DECLARE SIGNAL CHARACTER (20);
Attributes can also be implied by the presence of other attributes. For example, if the RETURNS attribute is specified for an identifier, the compiler supplies the ENTRY attribute by default.
The entry for each attribute in this chapter gives its syntax and abbreviation (if any) and describes related and conflicting attributes. See Table 2-1 for a concise alphabetic summary of PL/I attributes.
Computational Data Type Attributes
The attributes that define arithmetic and string data are:
You can specify these attributes for all elements of an array and for individual members of a structure.
Noncomputational Data Type Attributes
The following attributes apply to program data that is not used for computation:
Storage-Class and Scope Attributes
The following attributes control the allocation and use of storage for a computational variable and define the scope of the variable:
You can apply the following attributes to the major or minor members of a structure:
File Description Attributes
You can apply the following attributes to file constants and used in OPEN statements:
Entry Name Attributes
You can apply the following attributes to identifiers of entry points:
Nondata Type Attributes
You can apply the following attributes to data declarations:
Table 2-1 lists the PL/I attributes. The sections following this table describe each attribute in detail.
|ALIGNED||Requests alignment of bit-string variables in storage|
|ANY||Indicates that a parameter (of an external procedure not written in PL/I) can have any data type|
|AREA [(extent)]||Defines an area of storage for the allocation of based variables|
|Requests dynamic allocation of storage for a variable|
|BASED [(pointer-reference)]||Indicates that a variable's storage is located by a pointer|
|Defines a binary base for arithmetic data|
|BIT [(length)]||Defines bit-string data|
|BUILTIN||Defines a built-in function name|
|Defines character-string data|
|Defines an identifier as a condition name|
|Defines a variable whose storage is allocated and freed in successive and fixed-sequence generations|
|Defines a decimal base for arithmetic data|
|Indicates that a variable will share the storage allocated for another variable|
|Requests that an argument be passed to an external non-PL/I procedure by descriptor|
|Indicates that a variable is an array, and defines the number and extent of its dimensions|
|DIRECT||Specifies that a file will be only accessed randomly|
|ENTRY (descriptor,...)||Describes an external procedure and its parameters|
|Specifies system-dependent information about a file|
|Identifies the name of a variable whose storage is referenced or defined in other procedures|
|FILE||Identifies a PL/I file constant or file variable|
|FIXED [(precision[,scale-factor])]||Defines a fixed-point arithmetic variable|
|FLOAT [(precision)]||Defines a floating-point arithmetic variable|
|GLOBALDEF [(psect-name)]||Defines an external variable and optionally specifies the program section in which the variable will reside|
|GLOBALREF||Declares an external variable which is defined in an external procedure|
|Provides initial values for variables|
|INPUT||Specifies that a file will be used for input|
|Limits the scope of a variable to the block in which it is defined|
|KEYED||Specifies that a file can be accessed randomly by key|
|LABEL||Defines a label variable|
|LIKE structure-reference||Copies the declaration of a structure to another structure variable|
|LIST||Specifies that a parameter can accept a list of actual parameters, of arbitrary length|
|MEMBER||Specifies that an item is a member of a structure|
|Specifies that the length of a string is nonvarying|
|OFFSET [(area-reference)]||Defines an offset variable|
|OPTIONAL||Specifies, in the declaration of a formal parameter, that the actual parameter need not be specified in a call|
|OUTPUT||Specifies that a file will be used for output|
|Indicates that a variable will be assigned a value when it is used as an argument to a procedure|
|Specifies the format of numeric data stored in character form|
|Defines a pointer variable|
|Specifies the position within a variable at which a defined variable begins|
|Specifies the number of digits in an arithmetic variable and, with fixed-point data, the number of fractional digits|
|Specifies that a file is to be formatted for printing|
|READONLY||Specifies that a static variable's value does not change during program execution|
|RECORD||Specifies that a file will be accessed by record I/O statements|
|REFER||Defines dynamically self-defining structures|
|Requests that an argument be passed to an external non-PL/I procedure by reference|
|RETURNS (returns-descriptor)||Specifies that an external entry is a function and describes the value returned by it|
|Specifies that a file can be accessed sequentially|
|STATIC||Requests static allocation of storage|
|STREAM||Specifies that a file will be accessed by stream I/O statements|
|STRUCTURE||Specifies that a variable is a structure variable|
|TRUNCATE||Specifies, in a declaration of a formal parameter, that the actual parameter list can be truncated at the point where this argument should occur|
|TYPE||Copies declarations of structures, scalars, and arrays to another variable|
|Specifies nonalignment for bit-string variables in storage|
|UNION||Indicates that a variable will share the storage allocated for another variable|
|UPDATE||Specifies that records in a file can be rewritten or deleted|
|Requests either that a global symbol be accessed by value rather than by reference, or that an argument be passed to a procedure by immediate value|
|VARIABLE||Defines variable entry and file data|
|Defines a varying-length character string|