Sie sind auf Seite 1von 166

Open PL/I Language Reference Manual

Open PL/I Language Reference Manual


Contents
1. Language Concepts 1.1. Statements 1.2. Names 1.2.1. Declarations of Names 1.2.2. References to Names 1.3. Constants 1.4. Punctuation 1.5. Comments 1.6. Statement Sub-Groups 1.6.1. Compound Statements 1.6.1.1. IF Statement 1.6.1.2. ON Statement 1.6.1.3. DO Statement 1.6.1.4. SELECT Statement 1.6.2. Statements that Alter the Order of Execution 1.6.3. Statement that Handles Exception Conditions 1.7. Text Replacement and Insertion Statements 1.7.1. The %INCLUDE Statement 1.7.2. The %REPLACE Statement 1.8. Modules 1.9. Blocks 1.9.1. Procedure Blocks 1.9.1.1. Scope 1.9.1.2. Calls and Returns 1.9.1.3. Parameters and Arguments 1.9.1.4. Block Activation and Recursion 1.9.1.5. Guidelines for Using Procedures 1.9.1.6. Dynamic Fetching and Releasing of External Procedures 1.9.1.6.1. FETCH Statement 1.9.1.6.2. RELEASE Statement 1.9.1.6.3. Restrictions 1.10. BEGIN Blocks 1.11. Variables 1.11.1. Data Types and Conversion 1.11.2. Storage Classes 1.12. Files 1.12.1. File Constants 1.12.2. File Variables 1.12.3. Using Environment Variables 1.13. Input and Output 1.13.1. Stream I/O

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (1 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

1.13.1.1. List-Directed Stream I/O 1.13.1.2. Data-Directed Stream I/O 1.13.1.3. Edit-Directed Stream I/O 1.13.1.4. Terminal I/O on a Stream File 1.13.1.4.1. Stream File Attributes 1.13.1.4.1.1. Examples: 1.13.1.4.2. Print Files 1.13.2. Record I/O 1.13.2.1. Record File Attributes 1.13.2.2. Consecutive Record I/O 1.13.2.3. Indexed Record I/O 1.13.2.4. Relative Record I/O 1.13.2.5. REGIONAL(1) Record I/O 1.13.2.5.1. Example of REGIONAL(1) I/O 1.13.2.6. TITLE Options 2. Data Types 2.1. Introduction 2.2. Arithmetic Data 2.2.1. Fixed-Point Binary Literals 2.2.2. Floating-Point Binary Literals 2.2.3. Fixed-Point Data 2.2.4. Floating-Point Data 2.3. Picture Data 2.3.1. Picture Specification Characters 2.3.2. Rules for Using Numeric Picture Data 2.3.2.1. Drifting Characters and Strings 2.3.2.2. Credit and Debit Characters 2.3.3. Picture Repetition Factors 2.4. Character-String Data 2.4.1. String Repetition Factors 2.5. Wide Character-String Data (UTF-16 Support) 2.6. Bit-String Data 2.7. Area Data 2.8. Locator Data 2.8.1. Pointer Data 2.8.2. Offset Data 2.9. Label Data 2.10. Entry Data 2.10.1. Entry Constants 2.10.2. Entry Variables 2.10.3. Entry Values 2.10.3.1. The Stack Frame Designator 2.11. File Data 2.12. Arrays 2.13. Structures 2.14. Arrays of Structures 2.15. Data Size and Alignment
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (2 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

2.15.1. ALIGNED and UNALIGNED Attributes 3. Storage Classes 3.1. Introduction 3.2. Automatic Storage 3.3. Static Storage 3.4. Based Variables 3.5. Controlled Variables 3.6. Defined Variables 3.7. Parameter Storage Class 3.8. Storage Sharing 4. Declarations and Attributes 4.1. Introduction 4.2. Label Prefixes 4.3. DECLARE Statements 4.3.1. Recommended Forms 4.3.1.1. Simple Declarations 4.3.1.2. Factored Declarations 4.3.1.3. Structure Declarations 4.3.2. The General Form 4.3.3. Defaults 4.3.3.1. Compiler-supplied Defaults 4.3.3.2. The Default Statement 4.3.4. Attribute Consistency 4.4. Attributes of DECLARE Statements 4.4.1. ALIGNED 4.4.2. ANY 4.4.3. AREA 4.4.4. AUTOMATIC 4.4.5. BASED 4.4.6. BIGENDIAN 4.4.7. BINARY 4.4.8. BIT 4.4.9. BUILTIN 4.4.10. CHARACTER 4.4.11. CONDITION 4.4.12. CONNECTED 4.4.13. CONTROLLED 4.4.14. DECIMAL 4.4.15. DEFINED 4.4.16. DIMENSION 4.4.17. DIRECT 4.4.18. ENTRY 4.4.19. ENVIRONMENT 4.4.20. EXCLUSIVE 4.4.21. EXTERNAL 4.4.22. FILE 4.4.23. FIXED
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (3 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

4.4.24. FLOAT 4.4.25. GLOBALDEF 4.4.26. GLOBALREF 4.4.27. INITIAL 4.4.27.1. Examples of the INITIAL Attribute 4.4.28. INPUT 4.4.29. INTERNAL 4.4.30. IRREDUCIBLE 4.4.31. KEYED 4.4.32. LABEL 4.4.33. LIKE 4.4.34. NATIVE 4.4.35. NONNATIVE 4.4.36. OFFSET 4.4.37. OPTIONS(DESCRIPTOR) 4.4.38. OPTIONS(NODESCRIPTOR) 4.4.39. OPTIONS(VARIABLE) 4.4.40. OUTPUT 4.4.41. PICTURE 4.4.42. POINTER 4.4.43. POSITION 4.4.44. PRINT 4.4.45. READONLY 4.4.46. REAL 4.4.47. RECORD 4.4.48. REDUCIBLE 4.4.49. REFER 4.4.50. RETURNS 4.4.51. SEQUENTIAL 4.4.52. STATIC 4.4.53. STREAM 4.4.54. TYPE 4.4.54.1. TYPE Attribute Extensions 4.4.54.2. TYPE and Extent Expressions 4.4.54.3. Using the TYPE Attribute 4.4.54.4. Examples of the TYPE Attribute 4.4.55. UNALIGNED 4.4.56. UNION 4.4.57. UPDATE 4.4.58. VALUE 4.4.59. VARIABLE 4.4.60. VARYING 5. References 5.1. Introduction 5.2. Simple and Subscripted References 5.3. Structure Qualified References 5.4. Locator Qualified References
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (4 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

5.5. Procedure References 5.6. Built-In Function References 5.7. Variable References 5.8. Reference Resolution 6. Expressions 6.1. Introduction 6.2. Order of Evaluation 6.3. Array Expressions 6.3.1. Prefix Operators and Arrays 6.3.2. Infix Operators and Arrays 6.3.3. Array and Element Operations 6.3.4. Array and Array Operations 6.4. Types of Operators 6.4.1. Arithmetic Operators 6.4.2. Relational Operators 6.4.3. Bit-String Operators 6.4.4. The Concatenate Operator 7. Data Type Conversions 7.1. Introduction 7.2. Arithmetic to Arithmetic Conversion 7.3. Arithmetic to Bit-String Conversion 7.4. Arithmetic to Character-String Conversion 7.4.1. Case 1 7.4.1.1. Examples 7.4.2. Case 2 7.4.2.1. Examples 7.4.3. Case 3 7.4.3.1. Examples 7.5. Bit-String to Arithmetic Conversion 7.6. Bit-String to Character-String Conversion 7.7. Character-String to Arithmetic Conversion 7.8. Character-String to Bit-String Conversion 7.9. Format Controlled Conversion 7.9.1. F-Format 7.9.1.1. Input Conversion 7.9.1.2. Output Conversion 7.9.2. E-Format 7.9.2.1. Input Conversion 7.9.2.2. Output Conversion 7.9.3. A-Format 7.9.3.1. Input Conversion 7.9.3.2. Output Conversion 7.9.4. B-Format 7.9.4.1. Input Conversion 7.9.4.2. Output Conversion 7.9.5. P-Format 7.9.5.1. Input Conversion
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (5 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

7.9.5.2. Output Conversion 7.10. Pictured to Arithmetic Conversion 7.11. Pictured to Bit-String Conversion 7.12. Pictured to Character-String Conversion 7.13. Conversion to Pictured Data 8. Statements 8.1. Introduction 8.2. ALLOCATE 8.3. Assignment 8.3.1. Assignment - INT Pseudovariable 8.3.2. Assignment - ONCHAR Pseudovariable 8.3.3. Assignment - ONSOURCE Pseudovariable 8.3.4. Assignment - PAGENO 8.3.5. Assignment - POSINT Pseudovariable 8.3.6. Assignment - STRING Pseudovariable 8.3.7. Assignment - SUBSTR Pseudovariable 8.3.8. Assignment - UNSPEC 8.4. BEGIN 8.5. CALL 8.6. CLOSE 8.7. DECLARE 8.7.1. DECLARE - Array Format 8.7.2. DECLARE - Factored Format 8.7.3. DECLARE - Multiple Format 8.7.4. DECLARE - Outside of Procedure Format 8.7.5. DECLARE - Simple Format 8.7.6. DECLARE - Structure Format 8.8. DEFAULT 8.9. DELAY 8.10. DELETE 8.11. DISPLAY 8.12. DO 8.12.1. Simple DO Statement 8.12.2. DO WHILE and DO UNTIL Statements 8.12.3. DO REPEAT Statement 8.12.4. Iterative DO Statement 8.12.5. DO List Statement 8.12.6. Complex Iterative DO Statement 8.13. END 8.14. ENTRY 8.15. FETCH 8.16. FORMAT 8.17. FREE 8.18. GET 8.18.1. Edit-Directed Input 8.18.2. List-Directed Input 8.19. GOTO
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (6 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

8.20. IF 8.21. %INCLUDE 8.22. LEAVE 8.23. %LIST 8.24. %NOLIST 8.25. NULL 8.26. ON 8.27. OPEN 8.28. %OPTION 8.29. %PAGE 8.30. %POP 8.31. %PRINT 8.32. %NOPRINT 8.33. PROCEDURE 8.34. %PROCESS 8.35. *PROCESS 8.36. %PUSH 8.37. PUT 8.37.1. List-Directed Output 8.37.2. Data-Directed Output 8.37.2.1. Edit-Directed Output 8.38. READ 8.39. RELEASE 8.40. %REPLACE 8.41. RETURN 8.42. REVERT 8.43. REWRITE 8.44. SELECT 8.45. SIGNAL 8.46. %SKIP 8.47. STOP 8.48. WRITE 8.49. %XINCLUDE 9. Open PL/I Built-ins 9.1. Introduction 9.2. ABS Function 9.3. ACOS Function 9.4. ADD Function 9.5. ADDR Function 9.6. ADDRDATA 9.7. ALL Function 9.8. ALLOCATION Function 9.9. ANY Function 9.10. ASIN Function 9.11. ATAN Function 9.12. ATAND Function 9.13. ATANH Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (7 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

9.14. BINARY Function 9.15. BINARYVALUE Function 9.16. BIT Function 9.17. BOOL Function 9.18. BYTE Function 9.19. CEIL Function 9.20. CENTERLEFT / CENTRELEFT Function 9.21. CENTERRIGHT / CENTRERIGHT Function 9.22. CHARACTER Function 9.23. COLLATE Function 9.24. CONJG Function 9.25. COPY Function 9.26. COS Function 9.27. COSD Function 9.28. COSH Function 9.29. COUNT Function 9.30. CURRENTSTORAGE Function 9.31. DATAFIELD Function 9.32. DATE Function 9.33. DATETIME Function 9.34. DECIMAL Function 9.35. DIMENSION Function 9.36. DIVIDE Function 9.37. EMPTY Function 9.38. ERF Function 9.39. ERFC Function 9.40. EXP Function 9.41. FILEDDINT Function 9.42. FILEDDWORD Function 9.43. FILEOPEN Function 9.44. FIXED Function 9.45. FLOAT Function 9.46. FLOOR Function 9.47. FLUSH Subroutine 9.48. GRAPHIC Function 9.49. HBOUND Function 9.50. HEX Function 9.51. HIGH Function 9.52. INDEX Function 9.53. INT Function 9.54. LBOUND Function 9.55. LENGTH Function 9.56. LEFT Function 9.57. LINENO Function 9.58. LOG Function 9.59. LOG10 Function 9.60. LOG2 Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (8 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

9.61. LOW Function 9.62. LOWERCASE Function 9.63. LPIPARAMCOUNT Function 9.64. MAX Function 9.65. MAXLENGTH Function 9.66. MIN Function 9.67. MOD Function 9.68. MPSTR Function 9.69. MULTIPLY Function 9.70. NULL Function 9.71. OFFSET Function 9.72. ONCHAR Function 9.73. ONCODE Function 9.74. ONFILE Function 9.75. ONKEY Function 9.76. ONLOC Function 9.77. ONSOURCE Function 9.78. PACKAGENAME Function 9.79. PAGENO Function 9.80. PLIRETC Subroutine 9.81. PLIFILL Subroutine 9.82. PLIMOVE Subroutine 9.83. PLIOVER Subroutine 9.84. PLIRETV Function 9.85. PLISRTx Subroutines 9.86. PLITEST Subroutine 9.87. POINTER Function 9.88. POINTERADD Function 9.89. POINTERDIFF / PTRDIFF Function 9.90. POINTERSUBTRACT / PTRSUBTRACT 9.91. POINTERVALUE Function 9.92. POLY Function 9.93. POSINT Function 9.94. PRECISION Function 9.95. PROCEDURENAME() Function 9.96. PROD Function 9.97. RANDOM Function 9.98. RANK Function 9.99. REPEAT Function 9.100. RESIGNAL() Subroutine 9.101. REVERSE Function 9.102. RIGHT Function 9.103. ROUND Function 9.104. SEARCH Function 9.105. SEARCHR Function 9.106. SIGN 9.107. SIN Function
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (9 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

9.108. SIND Function 9.109. SINH Function 9.110. SIZE Function 9.111. SQRT Function 9.112. STORAGE Function 9.113. STRING Function 9.114. SUBSTR Function 9.115. SUM Function 9.116. SYSNULL Function 9.117. TALLY Function 9.118. TAN Function 9.119. TAND Function 9.120. TANH Function 9.121. TIME Function 9.122. TRANSLATE Function 9.123. TRIM Function 9.124. TRUNC Function 9.125. UNSPEC Function 9.126. UPPERCASE Function 9.127. VALID Function 9.128. VERIFY Function 9.129. WCHARVAL Function 9.130. WHIGH Function 9.131. WIDECHAR Function 9.132. WLOW Function 10. Open PL/I Macro Preprocessor 10.1. Overview 10.1.1. Preprocessor I/O 10.1.1.1. Preprocessor Statements 10.1.1.2. Listing Control Statements 10.2. Preprocessor Scan 10.3. Preprocessor Variables and Data Elements 10.4. Preprocessor References and Expressions 10.5. Scope of Preprocessor Names 10.6. Preprocessor Statements 10.6.1. %ACTIVATE 10.6.2. %ASSIGNMENT 10.6.3. %DEACTIVATE 10.6.4. %DECLARE 10.6.5. %DO 10.6.6. %END 10.6.7. %GOTO 10.6.8. %IF 10.6.9. %INCLUDE 10.6.10. %NOTE 10.6.11. %NULL 10.6.12. %REPLACE
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (10 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

10.7. Preprocessor Procedures 10.7.1. Invocation of Preprocessor Procedures 10.7.1.1. %PROCEDURE 10.7.1.2. RETURN 10.7.2. Preprocessor Built-In Functions 11. Features Unsupported by Open PL/I 11.1. Built-in Subroutines 11.2. Attributes 11.3. Options 11.4. Conditions 11.5. Statements 11.6. Constants 11.7. Items 11.8. Operations 11.9. Arrays 11.10. Others 12. Glossary

Open PL/I Language Reference Manual


This book provides a reference to the language used in Micro Focus Open PL/I.

Language Concepts This chapter provides an overview of the Open PL/I language, explaining the following basic concepts: program structure and statement syntax, block structure, variables, files, input and output. Data Types This chapter discusses the various data types that are available to you in Open PL/I. Storage Classes This chapter describes storage classes and how they are used. Declarations and Attributes This chapter explains how label prefixes and DECLARE statements are used for declarations, and also describes the attributes that can be used in a DECLARE statement. References This chapter describes each type of reference and the rules and basic steps involved in resolving references. Expressions This chapter explains expressions and how they are used. Data Type Conversions This chapter defines the conversions that result from assignments to arithmetic variables, bit-string variables, and pictured variables. Statements This chapter defines the Open PL/I statements. The statements are presented in alphabetical order by name.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (11 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Open PL/I Built-ins This chapter defines the built-in functions and subroutines provided by Open PL/I. Open PL/I Macro Preprocessor Features Unsupported by Open PL/I A list of features that are currently unsupported by Open PL/I. Glossary This chapter provides definitions for terms used in the Open PL/I manuals.

Parent topic: General Reference Related concepts Features added in Enterprise Developer 2.1 Related information Compiled File Types Delegates and Events IBM External Call Interface (ECI) To associate file extensions with COBOL Tutorials on COBOL and PL/I in the Visual Studio IDE Language Concepts

Send feedback about this topic

1. Language Concepts

Statements Names Constants Punctuation Comments Statement Sub-Groups Text Replacement and Insertion Statements Modules Blocks

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (12 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

BEGIN Blocks Variables Files Input and Output

Parent topic: Open PL/I Language Reference Manual Send feedback about this topic

1.1. Statements
Open PL/I is a block-structured language. Each block consists of a group of statements. Statements are used to declare constants and variables, and to express actions to be performed by your program. For example: READ FILE (G) INTO (Y) ; In this example, the READ statement reads the next record in file G into storage Y. Each Open PL/I statement consists of a series of elements ending with a semicolon. These elements can be PL/I keywords, user-specified identifiers, literal constants, or punctuation symbols. Parent topic: Language Concepts Send feedback about this topic

1.2. Names
A name used to denote part of a statement such as a verb, option, or clause, is called a keyword. All statements, except the assignment statement, begin with a keyword that identifies the purpose of the statement. A name can also denote an object operated upon by the program, such as a variable, file, or label. These names are known as identifiers. Their meanings are established by a declaration. In this example, G and Y are identifiers. READ, FILE, and INTO are keywords. READ FILE (G) INTO (Y) ; There are no reserved words in Open PL/I. In this example, TO names a storage location. GOTO L; CALL S(B,C,D); RETURN; STOP; DO K = 1 TO 11; TO = 20; /* ASSIGNMENT STATEMENT*/ The following example shows how names can either establish an object to be operated on or denote part of a
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (13 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

statement. DECLARE X(5) FIXED; L: X(3) = 25; Both X and L are identifiers, but DECLARE and FIXED are keywords. X is declared by a DECLARE statement; L is implicitly declared as a label. A name consists of any combination of the following:

letters digits _ (underscore character) @ (at sign character) # (pound sign character) $ (dollar sign character) a sequence of any of the above characters

The following rules apply to names.

Any of the alphanumeric characters A through Z, a through z, and 0 through 9 can be used. A name must not contain more than 32 characters. Names cannot contain blanks or hyphens.

Examples: STREET_NAME @BETA #Y7 C $7 Names can be written using both uppercase and lowercase letters. By default, all lowercase letters are interpreted as their uppercase equivalents. The -lowercase compiler option causes the reverse of this behavior. Refer to the Open PL/I User's Guide for more information on this option. Because there are no reserved names in Open PL/I. Names that are used as keywords, such as READ or INTO, can also be identifiers. However, this practice makes programs difficult to read and should be avoided whenever possible.

Declarations of Names References to Names

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (14 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Parent topic: Language Concepts Related information Open PL/I User's Guide

Send feedback about this topic

1.2.1. Declarations of Names


The meaning of a name is normally determined by its declaration. However, in some cases a name can be implicitly declared by the context in which it is used. (For more information, see the sections Compiler-supplied Defaults and DEFAULT .) The declaration of a name consists of a user-specified identifier and the attributes of that name. Open PL/I permits two kinds of explicit declarations: the DECLARE statement and the label prefix. The DECLARE statement declares the names of files, variables, and external procedures. A DECLARE statement can appear anywhere within the program, except as part of a compound statement. Regardless of where it appears, DECLARE is not an executable statement and has no effect except to establish the meaning of names. Examples: DECLARE F FILE; DECLARE A(5) FLOAT; DECLARE (I,J,K) FIXED BINARY(15); In the previous examples, F is declared as the name of a file constant; A is declared as a floating-point array variable; and I, J, and K are declared as integer variables. A label, also called a label prefix, is a user-specified identifier that names a statement so that it can be referenced elsewhere in your program. The label comes before the statement and is terminated with a colon (:). Examples: F: FORMAT(F(8,2),A(5)); P: PROCEDURE; L: READ FILE(F) INTO(X); In these examples, F is declared as a format name, P as a procedure name, and L as a statement label. Labels can appear on all Open PL/I statements except DECLARE statements, target statements of ON statements (called ON-units), ELSE or THEN clauses in IF statements, and WHEN or OTHERWISE clauses in SELECT statements. Parent topic: Names Related information Compiler-supplied Defaults DEFAULT ON

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (15 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Send feedback about this topic

1.2.2. References to Names


Use of a name in any context, other than in a declaration, constitutes a reference to the name. To determine the meaning of the reference, the Compiler searches for a declaration of the name. This search resolves the reference by associating it with a declaration. For example: DECLARE A FIXED BINARY(15); DECLARE B FLOAT; B = B+1; A = A+1; In the previous example, the Compiler knows that it must generate a floating-point add for B+1 because it has resolved the reference B to the second DECLARE statement. Likewise, it knows that it must generate an integer add for A+1 because it has resolved the reference A to the first DECLARE statement. Parent topic: Names Related information Reference Resolution

Send feedback about this topic

1.3. Constants
A constant is a sequence of characters that represents a particular, unchanging value. In Open PL/I, five kinds of constants are permissible:

Literal constants These are actual numbers or strings written in the source program. Literal constants are restricted to character strings, bit strings, and fixed- or floating-point numbers.

Label constants These are established using a label prefix in the source program that declares a name either as the name of a format or a procedure, or as a statement label. Label constants cannot be declared in a DECLARE statement.

File and entry constants These constants are typically established by DECLARE statements. File constants are identifiers declared with the FILE attribute to describe the type of input/output to be performed on a file. Entry constants are used to invoke procedures at certain entry points.

Replace constants These are identifiers that are to be changed with the %REPLACE statement. Like literal constants, constant identifiers can also be character strings, bit strings, and fixed- or floating-point decimal numbers.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (16 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Named constants These constants are scalar identifiers that are declared by the VALUE attribute. They can be declared for arithmetic data, string data, and for pointers and offsets.

Examples:

Constant

Type

25 7.5 3.12E-01 'How are you?' '1'B '1011'B '775'B3 'A7O'B4 STARTUPD: %REPLACE TABLE_SIZE BY 350; DECLARE E ENTRY; DECLARE F FILE;

Integer constant Fixed-point decimal constant Floating-point decimal constant Character-string constant Bit-string constant (binary notation) Bit-string constant (binary notation) Bit-string constant (octal notation) Bit-string constant (hexadecimal notation) Label constant TABLE_SIZE is an identifier to be replaced by an integer constant E is an entry constant F is a file constant

For a table showing the expansion of nonbinary notation into binary notation, see the section Bit-String Data. Arithmetic constants represent decimal values, whereas binary arithmetic values have no constant representation. Nevertheless, any decimal constant can be converted easily to a binary value by using it in a context that expects a binary arithmetic value. As a result of Open PL/I language rules, all constants that appear as floating-point numbers in a source program are actually of type float decimal and are subject to the rules of float decimal arithmetic. A character-string constant can contain any character, except that, if an apostrophe is required within a characterstring constant, it is written as two apostrophes. For example, 'He said, "I''m fine."' Note: The double quotation mark character is not equivalent to a single quotation mark or two adjacent single quotation marks and has no more significance than any other character within a constant. In Open PL/I, the maximum size of a string constant is 256 characters or bits (for details, see the section Open PL/I Compiler Implementation Limits). The Compiler checks this limit after bit-string constants written in the B2, B3, or B4 format have been expanded. Refer to the data type descriptions in the chapter Language Concepts in your Open PL/I

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (17 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

User's Guide for the maximum size limits for floating- and fixed-point data. A named constant is similar to a scalar declaration with the appropriate data attributes, plus the VALUE attribute. The VALUE attribute signifies this identifier is named constant, with all of the attributes taken as applied to the declaration. Named constants differ from simple constants in that they retain the attributes from the declaration. For example, declare i fixed bin (15) value(1); declare j fixed bin (15); j = 1; j = i; /* 1 is fixed decimal, requires conversion */ /* i is fixed bin (15), no conversion (integer 1 assigned, not "i" ) */

or string data items, the length is determined from the length of the string value when the length is not specified. declare string char value ('abcdef') ; /* string is char(6) */ In Open-PLI, named constants can be declared as arithmetic or string; pointers and offsets are not yet supported. In Open-PLI, the named constants may be declared before or after it is used, and the same scoping rules as any declaration apply. Example: cool: proc options(main); dcl pname char (16) value (procedurename()); dcl flag bit(1) aligned static init(true); dcl true bit(1) value ('1'b); dcl false bit(1) value('0'b); dcl myarr (n) fixed bin (15); dcl n fixed bin(15) value (800); dcl arr (k/3) fixed bin (15) static init (k+1, k, k+3); dcl arr1 (100+100) fixed bin (15); dcl arr2 (n+100) fixed bin (15); dcl i fixed bin (15); dcl k fixed bin (15) value (9); if flag then put skip list ('Named Constants are ', pname); put skip list(arr); i = n + 100; arr1 (k) = 99;

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (18 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

put skip list (size(arr1), size(arr2), i, arr1(K*2-K)); put skip list(arr); end; Named Constants are 10 400 10 COOL 9 1800 9

12 900 12

99

Parent topic: Language Concepts Related information Text Replacement and Insertion Statements Bit-String Data Open PL/I Compiler Implementation Limits B-Format Language Concepts

Send feedback about this topic

1.4. Punctuation
In Open PL/I, punctuation symbols are either operators or separators. Operators define the arithmetic or comparative operations to be performed on expressions in a statement. The table below lists the Open PL/I operators.

Symbol

Meaning

+ * ** / ^ or ~ | or ! & > < =

Addition or the plus prefix Subtraction or the minus prefix Multiplication Exponentiation Division Logical NOT Logical OR Logical AND Greater than Less than Equal to

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (19 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

^> or > ^< or < ^= or ~= >= <= || or !! >

Not greater than Not less than Not equal to Greater than or equal to Less than or equal to String concatenation Pointer resolution

Separators delimit and separate identifiers, keywords, and constants in statements. The table below lists the Open PL/ I separators.

Symbol

Meaning

() , (comma) ' (single quote) . (period) : ;

Encloses lists, defines order of expression evaluation, separates names of statements and options from specific keywords Separates subscripts and procedure arguments, separates identifiers in a structure name, and precedes the BY NAME option Delimits bit strings and character strings Specifies a decimal point. Connects elements of a qualified name Terminates a procedure name or a statement label Delimits statements

Names and constants may be separated from one another by one or more blanks, or tabs, rather than by separators. Additional blanks surrounding punctuation symbols are optional. In the following examples, blanks are represented by boxes ( ).

The first statement requires no blanks because each name is separated from the next by a punctuation symbol. The second statement shows the optional use of extra blanks. The third statement shows optional blanks surrounding the equal symbol (=) and after the semicolon, the remaining blanks being required blanks. Note that when an arithmetic constant is followed by a name, at least one blank or punctuation symbol is required to separate the arithmetic constant from the name. Parent topic: Language Concepts Send feedback about this topic

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (20 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

1.5. Comments
Comments are used to document an Open PL/I program. A comment can appear anywhere that a blank can appear and is equivalent to a blank. Comments cannot be nested. The general form of a comment is: /*Comments open with a slash* and close with a *slash */ For example, /*HERE IS A COMMENT*/ IF A<25 /* HERE IS ANOTHER ONE */ THEN /*HERE IS AN /* ERRONEOUS */ COMMENT */ The final comment is invalid because comments cannot be nested; it ends at the first * / in the line and the Compiler attempts to interpret COMMENT */ as code and produces an error message. The Compiler puts an asterisk (*) into the line number field of the listing file for each line on which a comment is continued from a preceding line. This convention can be used to determine if some text was accidentally included in a comment. Comments can continue over any number of lines of program text; thus, if the */ is omitted from a comment, all program text up to the next */ is considered part of the comment. This causes part of the program to be ignored by the Compiler and may cause it to produce misleading error messages. The same problem occurs if a character-string or bit-string constant is not terminated with an apostrophe. Parent topic: Language Concepts Send feedback about this topic

1.6. Statement Sub-Groups


This section introduces certain Open PL/I statements that, alone or in conjunction with other statements, provide specific capabilities within Open PL/I.

Compound Statements Statements that Alter the Order of Execution Statement that Handles Exception Conditions

Parent topic: Language Concepts Related information Statements

Send feedback about this topic

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (21 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

1.6.1. Compound Statements


Open PL/I has four compound statements:

IF ON DO SELECT

They are called compound statements because they each contain other statements.

IF Statement ON Statement DO Statement SELECT Statement

Parent topic: Statement Sub-Groups Send feedback about this topic

1.6.1.1. IF Statement
The IF statement tests an expression and performs a specified action if the result of the expression is true. Its general form is: IF expression THEN statement; [ELSE statement]; where expression is any valid expression that yields a scalar bit-string value, and statement is any unlabeled statement (except DECLARE, END, ENTRY, FORMAT, or PROCEDURE) or an unlabeled DO-group or BEGIN block. For example: IF A>B THEN READ FILE (F) INTO (X); In this example, the IF statement contains the READ statement. If the expression A>B is true, the READ statement executes. The IF statement needs no semicolon of its own because each statement contained within it has its own semicolon. IF statements can be nested, as shown in the following example.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (22 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

IF A>B THEN IF D<C THEN READ FILE(F) INTO(X); ELSE STOP; In this example, the second IF statement has both a THEN clause and an ELSE clause. An ELSE clause always corresponds to the THEN clause that immediately precedes it. The first IF statement has only a THEN clause. If you want to STOP when A ^> B, you may provide a null ELSE clause to the innermost IF, forcing the ELSE STOP to be associated with the first IF. It is preferable to use structured IF, THEN, and DO statements to accomplish this, as shown in the following example. IF A>B THEN DO; IF D<C THEN READ FILE(F) INTO (X); END; ELSE STOP;

Parent topic: Compound Statements Send feedback about this topic

1.6.1.2. ON Statement
The ON statement defines the action to be taken when a specific condition is signaled during the execution of a program. Its general form is: ON conditionname ON-unit, or ON conditionname SYSTEM where: condition-name is ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, KEY(f), OVERFLOW, RECORD(f), SIZE, UNDEFINEDFILE(f), UNDERFLOW, USERCONDITION(expression), USERCONDITION(SS$_UNWIND), or ZERODIVIDE. ON-unit is a BEGIN block or any statement other than DECLARE, DEFAULT, DO, END, ENTRY, FORMAT, LEAVE, OTHERWISE, PROCEDURE, RETURN, or SELECT. The keyword SYSTEM indicates that, instead of executing user-specified code in the ON-unit, a system-generated message describing the condition is displayed and the ERROR condition is signaled. For example: ON ENDFILE (F ) BEGIN; . . . END; In this example, the block of statements between the BEGIN and END statement executes if the end-of-file condition is reached.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (23 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

ON is a compound statement, but it cannot be nested. The ON statement's use in responding to exceptional conditions is explained more fully in the section Statement that Handles Exception Conditions. Parent topic: Compound Statements Related information Statement that Handles Exception Conditions

Send feedback about this topic

1.6.1.3. DO Statement
The DO statement begins a sequence of statements to be executed in a group, called a DO-group. Its general form is: DO; . . . END; For example: IF B < C THEN DO; PUT LIST ('ADDED DATA REQUIRED'); GET LIST (VALUE); B = B + VALUE; END; In this example, the PUT LIST, GET LIST, and assignment statements execute if B < C. DO statements can contain IF statements, other DO-groups, RETURN statements, or GOTO statements that alter the order of execution. Parent topic: Compound Statements Send feedback about this topic

1.6.1.4. SELECT Statement


The SELECT statement tests a series of expressions and performs the action specified with the first true test, or the action associated with the OTHERWISE clause (if present) and none of the tests evaluates true. Its general form is: SELECT[select-expression]; WHEN (e1[,e2[,e3[...]]]) WHEN (e4[,e5[,e6[...]]]) . . action_1; action_2;

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (24 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

. [OTHERWISE action_m;] END; where select-expression and e1, e2... are valid expressions, and each action is a single or compound statement or a BEGIN block. For example: SELECT; WHEN (F=40) G=G+1; WHEN (F=50) IF G > 0 THEN G=G+2; . . . OTHERWISE DO; . . . END; END; This example shows the SELECT statement used with the expression omitted. When the expression is omitted from the SELECT statement, each WHEN clause expression is evaluated and converted, if necessary, to a bit string. The action after the WHEN clause is performed if the resulting bit string is nonzero. In the above example, if F=40 is true, the action G=G+1 is executed and the SELECT group is exited. If F=50 is true, the IF statement is executed and the SELECT group is exited. If more than one WHEN statement is true, the action associated with the first true WHEN clause is executed. If no WHEN clauses are true, the DO group associated with the OTHERWISE clause is executed. When control reaches a SELECT statement with a selectexpression present, the select-expression is evaluated and its value saved. Next, the expressions in the WHEN clauses are evaluated in the order in which they appear, and each value is compared with the value of selectexpression. If a value is found that is equal to the value of select expression, the action following the corresponding WHEN clause is performed, and no further WHEN clause expressions are evaluated. If none of the expressions in the WHEN clauses is equal to the selectexpression, the action specified after the OTHERWISE clause is executed unconditionally. for more information, see the section SELECT in the chapter Statements. Parent topic: Compound Statements Related information SELECT

Send feedback about this topic

1.6.2. Statements that Alter the Order of Execution


Statements are typically executed in the order in which they are written; however, certain statements control the order of execution of the program. These statements are GOTO (used with a statement label), IF, and DO. The GOTO statement causes control to be transferred to a labeled statement in the current procedure or in another active procedure. Its general form is: GOTO labelreference[OTHERWISE];

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (25 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

or GO TO labelreference[OTHERWISE]; where: labelreference is a label constant or an expression that, when evaluated, yields a label value. (A label value denotes a statement in the program.) For example: A = 5; GOTO L2; L1: B = 7; . . . L2: B = 4; In this example, A is assigned 5 and B is assigned 4. The statements beginning with label L1 can be executed only if a GOTO statement transfers control to the label L1. Although labels are a convenient means to represent a specific location in a program, programs that contain many labels are generally more difficult to read and modify. The use of labels and GOTOs can be avoided or minimized by using the compound statements IF and DO to control the order of statement execution. The DO statement causes all statements between the DO statement and its corresponding END statement to be executed a number of times as determined by the form of the DO statement. Parent topic: Statement Sub-Groups Send feedback about this topic

1.6.3. Statement that Handles Exception Conditions


The ON statement gives your Open PL/I programs the ability to respond to exception conditions that occur during the execution of a program, such as end-of-file, or computational errors such as division by zero. For example: ON ERROR BEGIN; . . . END; Execution of the ON statement establishes the ON-unit as a block of statements that are executed if the specified condition occurs. If the specified condition occurs after the ON statement is executed, processing is interrupted and the specified ONunit is executed. In the above example, the block of statements between the BEGIN and END statements are established as the ONunit, which executes if the ERROR condition occurs. Execution of the ON statement does not cause immediate execution of the ON-unit. An ON-unit is established within its containing block's current activation and remains established until that block returns to its caller, or until another ON-unit is established for the same condition within the same block activation, or
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (26 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

until the ON-unit is reverted using the REVERT statement. If one of the possible conditions occurs during the execution of a block, and that block does not have an established ON-unit for that condition, the calling block's ON-unit is used to respond to the condition. If the calling block has no established ON-unit for the condition, its caller's ON-unit is used, and so on. If no ancestor has an ON-unit for the condition, a default action is taken. Except for the ENDPAGE, FINISH, and UNDERFLOW conditions, this default action ends program execution and issues a run-time error message. ON-units for the ERROR condition cannot resume execution of the statement in which the error was detected. Parent topic: Statement Sub-Groups Send feedback about this topic

1.7. Text Replacement and Insertion Statements


When a program module is being compiled, the Compiler is able to recognize and evaluate two statements that alter the program text: %INCLUDE and %REPLACE. Both of these statements can be used anywhere within a procedure or source file to simplify the job of writing programs. Other statements that alter program text are described in Open PL/I Macro Preprocessor.

The %INCLUDE Statement The %REPLACE Statement

Parent topic: Language Concepts Related information Open PL/I Macro Preprocessor

Send feedback about this topic

1.7.1. The %INCLUDE Statement


The %INCLUDE statement incorporates text from other files into the current source file during compilation. The general form of this statement is: %INCLUDE filename[,filename]...; where: filename is one of the following:

A character string An Open PL/I name

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (27 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

An Open PL/I name enclosed in parentheses

The specified filename is used to locate a text file whose content is inserted into the program text in place of the % INCLUDE statement. Your selection of one of these forms in combination with the presence or absence of the -ipath compiler option affects the search pattern used in locating files to be included. For more information, see the section %INCLUDE in the chapter Statements. Note: The Open PL/I Macro Preprocessor has its own %INCLUDE statement. Its use is documented in the appendix Open PL/I Macro Preprocessor.

Parent topic: Text Replacement and Insertion Statements Related information %INCLUDE Open PL/I Macro Preprocessor

Send feedback about this topic

1.7.2. The %REPLACE Statement


The %REPLACE statement specifies that an identifier is to be replaced by a specified constant or other name during compilation. The general form of this statement is: %REPLACE name BY constant-or-name; Beginning at the point at which the %REPLACE statement is encountered, each occurrence of name that follows the % REPLACE statement is replaced by the specified constant or other name until the end of compilation. The %REPLACE statement is often used to supply the sizes of tables or to give names to special constants whose meaning would not otherwise be obvious. For example: %REPLACE TRUE BY '1'B; %REPLACE TABLE_SIZE BY 400; %REPLACE MOTOR_POOL BY 5; %REPLACE X BY -3.0E0; DECLARE X(TABLE_SIZE) FIXED STATIC; DO K = 1 TO TABLE_SIZE; IF DEPARTMENT_NUMBER = MOTOR_POOL THEN DO; . . . Both the %REPLACE and %INCLUDE statements operate on the program text without regard to the meaning of the text. The %REPLACE statement substitutes all subsequent occurrences of the name without regard to the block structure
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (28 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

of the module, as explained in the section Blocks. Parent topic: Text Replacement and Insertion Statements Related information Blocks

Send feedback about this topic

1.8. Modules
One or more external procedures can be present within a single Open PL/I source file. All external procedures within a source file will be compiled by the Compiler into a single object file. A module is defined as a single compilation unit, a source file that is compiled into object code. A module consists of one or more external procedures. A source file may contain declarations that appear outside the scope of any external procedure, as long as all variables that appear in such declarations are BASED, STATIC, or DEFINED. A variable that is defined this way is known within the scope of all external procedures. If a declaration is provided with the EXTERNAL attribute, it will be known outside the source file. A source file may also contain %REPLACE statements and declarations of named constants (for example, file and entry constants) before the first external procedure. The following example illustrates a source file that has declarations and %REPLACE statements preceding the first external procedure. There are two procedures (GETREC and PUTREC) in the source file that can be used as part of the program. By default, Open PL/I declares these entry constants, GETREC and PUTREC, with the EXTERNAL attribute; therefore, a procedure from another module outside of this source file can invoke GETREC or PUTREC. If a procedure in another module needs to reference GETREC and PUTREC, they must be declared within that module with the attributes ENTRY and EXTERNAL. At the top of this source file are other items (REC, NAME, ADDRESS) that are hidden from any procedures compiled in other modules, and are known only to GETREC and PUTREC. Because Open PL/I, by default, provides file constant declarations with the EXTERNAL attribute, the file DATA_BASE can be known in other modules. %REPLACE DATA_SIZE BY 80; DECLARE 1 REC BASED 2 NAME CHAR(40), 2 ADDRESS CHAR(DATA_SIZE); DECLARE DATA_BASE KEYED FILE UPDATE; GETREC: PROCEDURE(P); DECLARE P POINTER; READ FILE(DATA_BASE) INTO(P->REC); END GETREC; PUTREC: PROCEDURE(P); DECLARE P POINTER; REWRITE FILE(DATA_BASE) FROM(P->REC); END PUTREC;

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (29 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Parent topic: Language Concepts Send feedback about this topic

1.9. Blocks
PL/I is a block-structured language. Just as certain language elements make up statements, groups of statements make up blocks. Two types of blocks exist in Open PL/I:

Procedure blocks BEGIN blocks

A procedure block is the basic executable program unit of Open PL/I and is made up of a group of statements contained within the limits of a pair of statements, PROCEDURE and END. A BEGIN block is a program unit into which control flows during the typical execution of a procedure. The statements within a BEGIN block are contained within the limits of a pair of statements, BEGIN and END. Whenever a procedure block or BEGIN block is entered, a block activation is created for that block. The block activation consists of the allocation of storage for the variables declared within the block and the system information that links that block to the previous block in the activation chain. The following sections provide detailed information on procedure and BEGIN blocks and activation of these blocks.

Procedure Blocks

Parent topic: Language Concepts Send feedback about this topic

1.9.1. Procedure Blocks


A procedure is a sequence of statements beginning with a PROCEDURE statement and ending with an END statement. The purpose of a procedure is to "package" a set of executable statements and declarations to form a block that can be executed from several places in the program simply by calling it. Because a procedure defines a block of statements, it is typically called a procedure block. The following example shows two procedure blocks, A and B: A: PROCEDURE; . . . END A; B: PROCEDURE; . . . END B;
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (30 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Procedures contained within other procedures are called nested or internal procedures. Procedures not contained within other procedures are called external procedures. A program module consists of one or more external procedures. For example: A: PROCEDURE; . . . B: PROCEDURE; . . . END B; C: PROCEDURE . . . D: PROCEDURE; . . . END D; END C; END A; In this example, Procedure A is external, and procedures B and C are nested within it. Procedure D is nested within procedure C.

Scope Calls and Returns Parameters and Arguments Block Activation and Recursion Guidelines for Using Procedures Dynamic Fetching and Releasing of External Procedures

Parent topic: Blocks Send feedback about this topic

1.9.1.1. Scope
Each procedure block establishes a distinct region of the program text called "scope," throughout which the names declared within that procedure block are known. The scope of a name is defined as the region of the program in which the name has meaning and can be referenced.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (31 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

The scope of a name includes the procedure in which the name is declared and all procedures contained within that procedure, except those contained procedures in which the same name is redeclared. For example: A: PROCEDURE; DECLARE (X,Y) FLOAT; . . . B: PROCEDURE; DECLARE X FILE; DECLARE Z FIXED; . . . END B; END A; In this example, the scope of Y includes both procedure A and procedure B. The scope of X as a float is only procedure A. The scope of X as a file is procedure B. The scope of Z is procedure B. Z cannot be referenced from within procedure A. The scope of the procedure name B includes both procedure A and procedure B. Parent topic: Procedure Blocks Send feedback about this topic

1.9.1.2. Calls and Returns


Statements within a procedure block are executed only when the procedure block is called from another procedure block. The CALL statement enables procedure calling. For example: A: PROCEDURE; . . . CALL B; . . . B: PROCEDURE; . . . END B; . . . END A; In this example, procedure B is executed only when it is called from procedure A. Procedure A resumes execution at the statement following the call when B is completed. A procedure returns to its caller either by executing its END statement or by executing a RETURN statement, as
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (32 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

shown in the following example: A: PROCEDURE; . . . IF X<0 THEN RETURN; . . . END A; Control does not "flow" into a procedure; that is, if control reaches a statement immediately preceding a procedure declaration, then (unless the statement is a control-flow statement such as GOTO) control will automatically skip to the statement following the declared procedure. Parent topic: Procedure Blocks Send feedback about this topic

1.9.1.3. Parameters and Arguments


The usefulness of a procedure block is increased greatly if it can be made to operate on different values each time it is called. Arguments and parameters enable such operation. Arguments are the values passed to a procedure block at invocation. Parameters are the names used by the invoked procedure block to refer to these arguments. Open PL/I typically passes an argument to an invoked procedure by referencing its storage address. For example: CALL P(A,B); . . . CALL P(D,E); . . . P: PROCEDURE(X,Y); . . . PUT FILE (F) LIST(X,Y); . . . END P; In this example, A and B are arguments of the first call to the procedure P. While P is executing as a result of the first call, the argument A is said to correspond to the parameter X and the argument B corresponds to the parameter Y. While P is executing as a result of the second call, D corresponds to X and E corresponds to Y.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (33 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

When an argument is a variable, the actual address of the variable is passed to the called procedure. This allows the invoked procedure to change the value of the argument. When an argument is a constant or an expression, a temporary location is used to store the current value of the argument, and the address of that temporary location is passed to the called procedure. Parent topic: Procedure Blocks Send feedback about this topic

1.9.1.4. Block Activation and Recursion


Each time a procedure block is called, it is said to be active, and it remains active until it returns from the call (or until a non-local GOTO transfers control to a containing block activation). Such procedure activation has an associated block of storage allocated on a stack. This block of storage is called a stack frame, and it is used to hold information (such as the location to which control should return from the activation) that is unique to each procedure activation. The stack frame contains storage for the automatic data declared within the block. Thus, each activation of the block has its own copy of the automatic data. If procedure A calls procedure B, the stack frame associated with the activation of A is pushed down by the stack frame associated with the activation of B. When B returns, its stack frame is popped from the stack and the stack frame of A is then the current stack frame. If procedure A calls itself directly or indirectly by invoking a chain of procedures in which A is again called, A is said to be a recursive procedure. For example: A: PROCEDURE RECURSIVE; . . . CALL A; . . . END A; The following example shows a program that makes a copy of a tree structure using block activation and recursion principles. . . NEW = COPY(OLD); . . COPY: PROCEDURE(IN) RETURNS(POINTER)| RECURSIVE; DECLARE (IN,OUT) POINTER; DECLARE 1 RECORD BASED, 2 FIELD1 FLOAT, 2 FIELD2 FLOAT, 2 DAUGHTER POINTER, 2 SON POINTER; DECLARE NULL BUILTIN;
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (34 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

IF IN = NULL THEN RETURN(NULL); ALLOCATE RECORD SET(OUT); OUT->RECORD.FIELD1 = IN->RECORD.FIELD1; OUT->RECORD.FIELD2 = IN->RECORD.FIELD2; OUT->RECORD.DAUGHTER = COPY(IN->RECORD.DAUGHTER); OUT->RECORD.SON = COPY(IN->RECORD.SON); RETURN(OUT); END COPY; As demonstrated in this example, each record of the original tree structure may be linked using pointers to a SON record and/or a DAUGHTER record. Either the SON or the DAUGHTER field may contain a null pointer value. COPY is called with a pointer to the root in the original tree structure. It returns a pointer to the root in a new tree structure that is a copy of the original. Each activation of the COPY procedure has its own instance of the variables IN and OUT. For additional information about recursive procedures, see the section Entry Data in the chapter Data Types. Parent topic: Procedure Blocks Related information Entry Data

Send feedback about this topic

1.9.1.5. Guidelines for Using Procedures


Procedures are a natural division of the program and therefore provide the best mechanism to represent program modularity. The program should be organized or structured as a set of modules, each of which is written as a procedure. Adhere to the following guidelines when using procedures:

Write procedures with minimal dependence on their ability to access the values of their containing procedure. All such use of nonlocal variables should be clearly documented by comments in both the declaring and the using procedures. Write procedures that are used only from within a given procedure as internal procedures within the calling procedure. Write internal procedures following the executable statements of the containing procedure. Make each procedure as small as possible to enable understanding of program logic.

Parent topic: Procedure Blocks Send feedback about this topic

1.9.1.6. Dynamic Fetching and Releasing of External Procedures


An external procedure can be dynamically fetched or released by a program. This means that it can be loaded or deleted by the program using the FETCH and RELEASE statements. When the procedure is not in main storage, it
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (35 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

can be loaded into it and then deleted from it at any time during the execution of the calling procedure. This is useful when it is not necessary to call the external procedure every time when the calling procedure is executed. A procedure has to be loaded into main storage before it can be executed, unless it is already there. Once loaded, the procedure can remain in main storage until the execution of the whole program is completed, or it can be deleted at any time using the RELEASE statement. A fetched procedure is compiled and linked separately from the calling procedure. For more information, see Compiling, Linking and Debugging of Fetchable Procedures. Whenever the load module containing the fetched procedure is loaded into memory, the STATIC variables in the fetched procedure are given the initial values indicated by their declarations. Note that EXTERNAL files and CONDITION conditions are shared across the whole application, including the fetched procedures.

FETCH Statement RELEASE Statement Restrictions

Parent topic: Procedure Blocks Related information Compiling, Linking and Debugging of Fetchable Procedures

Send feedback about this topic

1.9.1.6.1. FETCH Statement


Purpose
Dynamically loads an external procedure into main storage.

Syntax
FETCH entry-constant [SET(ptr-ref)][TITLE (char-expr)]

Parameters
entry-constant The name by which the loaded procedure is known to the operating system. It is the same as the one used in the corresponding CALL statement, or CALL option of an INITIAL attribute, or function reference.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (36 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

ptr-ref A pointer reference that is set to the address of the entry point of the module that is loaded. char-expr Any character expression.

Description
The FETCH statement is used to dynamically load modules into main storage. It must specify an entry constant, which is the name by which the fetched procedure is known to the operating system. When this name is referenced in a FETCH statement, the procedure can also be loaded into main storage when a CALL statement, or a CALL option of an INITIAL attribute, or a function reference is executed.

Restrictions
See Restrictions under Dynamic Fetching and Releasing of External Procedures. Parent topic: Dynamic Fetching and Releasing of External Procedures Related reference RELEASE Statement Related information Dynamic Fetching and Releasing of External Procedures

Send feedback about this topic

1.9.1.6.2. RELEASE Statement


Purpose
Deletes from main storage a previously fetched procedure.

Syntax
RELEASE entry-constant

Parameters
entry-constant The RELEASE statement must specify an entry constant. It is the name by which the loaded procedure is known to the operating system. It is the same as the one used in the corresponding FETCH statement, CALL statement, CALL option of an INITIAL attribute, or function reference.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (37 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Description
The RELEASE statement releases (deletes) from main storage a previously fetched modules. RELEASE * deletes all previously fetched modules. It must not be executed from within a fetched module.

Restrictions
See Restrictions under Dynamic Fetching and Releasing of External Procedures. Note: RELEASE* is not currently supported but an API can be provided if this functionality is needed.

Parent topic: Dynamic Fetching and Releasing of External Procedures Related reference FETCH Statement Related information Dynamic Fetching and Releasing of External Procedures

Send feedback about this topic

1.9.1.6.3. Restrictions

If you have an ON CONVERSION on unit that is located in the main program and triggered by a fetchable procedure, or located within a fetchable procedure and triggered within another fetchable procedure that is subordinate to it on the callstack, then the ONCHAR() and ONSOURCE() built-in functions will not correctly "reset" the triggering variables values within the fetchable procedure that caused the condition. If the ON CONVERSION on unit is within the triggering fetchable procedure (or main program), then there is no problem. If the fetchable module has its procedure declared with OPTIONS(MAIN) or if when linking you specify the options -cics, -ims, or -mvs, then your fetchable routine will have its own runtime context and ON UNIT's memory chains, and file variables will not be shared across fetchable boundaries. For any program which does any form of file I/O, the following needs to be done:
r

For each FILE declaration it must have storage allocated to its FILE constant. This is achieved through the use of the -defext compile option and/or through the use of an optional parameter called GLOBALDEF. It is important that within a fetchable procedure or a program compiled with OPTIONS (MAIN), this is done exactly one time per FILE constant. If this is not done, the results are completely unpredictable and the behaviors will not be supported. For typical usage, compiling with -defext is more than adequate. If you have two or more subroutines which are all accessing the same FILE constant, and they are linked into a single fetchable procedure or program, only one of the programs should be compiled with -defext. As an alternative approach you can add the attribute GLOBALDEF to one of the file declarations and not use the -defext switch for any of the compiles.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (38 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Parent topic: Dynamic Fetching and Releasing of External Procedures Send feedback about this topic

1.10. BEGIN Blocks


A BEGIN block is a sequence of Open PL/I statements into which control flows during the routine execution of a program. A BEGIN block differs from a procedure in that it is invoked by executing its BEGIN statement, it cannot have any parameters, and it always returns by executing its END statement. In addition, execution of a RETURN statement within a BEGIN block returns to the caller of the procedure that immediately contains the BEGIN block. And, unlike a procedure, a BEGIN block can be used as the ONunit of an ON statement. The BEGIN block groups a set of program statements and defines a scope for the names declared within it. Generally, the reason for using a BEGIN block is to create a new scope and/or a new block activation. BEGIN blocks can contain DO-groups, SELECT groups, DECLARE statements, and procedures, as well as other BEGIN blocks. The statements of a BEGIN block are bounded by BEGIN and END statements, as shown in the following example: BEGIN; . . . END; Since the BEGIN block contains declarations and ON-units, as well as executable statements, it can be used to permit temporary redefinitions of names and exception handlers, as well as to provide a means of allocating and freeing AUTOMATIC variables within it. (For additional information about AUTOMATIC variables, see the section Storage Classes.) For example: DECLARE SUM FIXED BINARY; . . . BEGIN; DECLARE SUM FILE; DECLARE X(1000) FLOAT; . . . END; In this example, SUM is redeclared within the BEGIN block so that it can be used as a file. A large array X is declared within the BEGIN block and is allocated storage only during the execution of the BEGIN block. Parent topic: Language Concepts Related information Storage Classes

Send feedback about this topic

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (39 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

1.11. Variables
A variable is a named object that is capable of holding values. Each variable has two properties: Data type Determines the kind of values a variable holds. Storage class Determines the duration of a variable's existence and how it is referenced.

Data Types and Conversion Storage Classes

Parent topic: Language Concepts Send feedback about this topic

1.11.1. Data Types and Conversion


Each variable must be declared to have a data type. Except for cases under control of the DEFAULT statement, failure to specify a data type causes the Compiler to issue a warning and to give the variable a data type of Fixed Binary(15) if its name begins with any of the letters I through N; otherwise, the variable is given a data type of Float Decimal(6). A complete discussion of data types is contained in the chapter Data Types. The following examples show several data types available in Open PL/I. Examples: DECLARE DECLARE DECLARE DECLARE A N C B FLOAT DECIMAL(7); FIXED BINARY(15); CHARACTER(30); BIT(1);

In these examples, variable A is capable of holding any floating-point decimal value with mantissa of up to 7 digits and exponent of up to 3 digits; variable N is capable of holding any binary integer value between -32768 and +32767 inclusive; variable C is capable of holding any string of 30 characters; and variable B is capable of holding either '1'B or '0'B. Although each variable is capable of holding values of only a specific data type, the Open PL/I language provides a complete set of operations that convert values from one data type to another. Whenever a value is assigned to a variable, it is first converted to the data type of the variable, as illustrated in the following examples (which refer to the declarations in the previous examples). Examples: A N C B = = = = 1; /* converts 1 to FLOAT DECIMAL(7) */ 2.5; /* converts 2.5 to the FIXED BIN(15) integer 2 */ -4.5; /* converts -4.5 to a character string */ 0; /* converts integer 0 to '0'B */

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (40 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

For a complete discussion of data type conversions, see the chapter Data Type Conversions. Parent topic: Variables Related information Data Types Data Type Conversions

Send feedback about this topic

1.11.2. Storage Classes


A variable's storage class determines when and for how long storage is to be allocated for the variable. Since this storage holds the variable's value, the storage class of a variable determines how long the variable retains its value. The Open PL/I language permits the following six storage classes, which are fully explained in the chapter Storage Classes.

AUTOMATIC BASED CONTROLLED DEFINED STATIC (INTERNAL or EXTERNAL) parameter

Unless declared otherwise, a variable's storage class is AUTOMATIC, meaning that it is allocated storage each time its immediately enclosing scope becomes active (as happens during a procedure call or the execution of a BEGIN statement. Exiting the scope frees this allocated storage (as happens at procedure or BEGIN block termination). Consequently, AUTOMATIC variables do not retain their values after deactivation of the block in which they are contained. If a variable must retain its value between calls of its containing procedure, it should be declared to have the STATIC storage class. For example: DECLARE K FIXED BINARY STATIC; DECLARE TABLE(4) CHARACTER(5) STATIC INITIAL('A','B','C','D'); In this example, each element of the array TABLE is given an initial value. Storage for STATIC variables is allocated prior to program execution by the Compiler and linker. Consequently, the length (precision) of each STATIC variable must be constant at compile time. Parent topic: Variables

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (41 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Related information Storage Classes

Send feedback about this topic

1.12. Files
In Open PL/I, a file is a source of input data or a target for data output. Files are referenced in I/O statements by using a file name declared with the FILE attribute. The file reference actually refers to a file constant or to a file variable that has been assigned a value. Each file used by the program must be declared in exactly one module in the program. That module must either declare the file with the GLOBALDEF attribute or must be compiled with the -defext option.

File Constants File Variables Using Environment Variables

Parent topic: Language Concepts Send feedback about this topic

1.12.1. File Constants


A file constant is an identifier declared with the FILE attribute and without the VARIABLE attribute. For example: DECLARE F FILE; In this example, F is the name of a file constant. A file constant cannot be the target of an assignment operation, and is external, by default. (For a discussion of assignment statements, see the chapter Statements.) Each file constant is associated with a block of static storage called a file control block. The file control block retains information about the current status of the file while the file is open. In effect, the file constant is a pointer to, or a designator of, a file control block. File constants require the use of the -defext compiler option. Each file control block's file identifier (ID) is the NAME of its associated file constant. The file ID in the previous example is F. This ID is used as the default TITLE of the file when it is being opened. Parent topic: Files Related information Statements

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (42 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Send feedback about this topic

1.12.2. File Variables


A file variable is a variable that can be assigned file values. A file variable can be given a value by receiving a file constant passed as an argument, by receiving a file constant as the value of a function, or by simple assignment. A file variable is declared with the VARIABLE attribute. For example: DECLARE G FILE; DECLARE F FILE; DECLARE V FILE VARIABLE; V=F; ... V=G; In this example, F and G are file constants, each of which has an associated file control block. V is a file variable that can be assigned file values. After the first assignment, both F and V designate the same file control block. Any operation performed on V is equivalent to the same operation performed on F. After the second assignment, any operation performed on V is equivalent to the same operation performed on G, because both V and G designate the same file control block. A file name used as a parameter is a file variable and designates the same file control block as its corresponding argument. Parent topic: Files Send feedback about this topic

1.12.3. Using Environment Variables


To determine the system name of a file to match with a PL/I file, Open PL/I uses the name specified in the TITLE option of the OPEN statement. If the TITLE option is omitted, Open PL/I uses, by default, the name of the file constant or file variable in the PL/I program (shifted to uppercase). You can, instead, use system environment variables to easily specify the system names of files at run-time. The environment variable must be named in this fashion: LPI_name system-filename where: name is the TITLE-specified or default name indicated by the program. Examples: DECLARE DATA2 UPDATE FILE; DECLARE FACTS STREAM FILE; OPEN FILE(DATA2) /* no title */; OPEN FILE(FACTS) TITLE('Report');

If you do not use environment variables to connect these openings with systems files, the following system names will be assumed for the files: DATA2 and Report. Instead, prior to running the application, you could set environment variables as follows, causing the specified system files to be used. (Any directories used in the path names must exist.)

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (43 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

setenv LPI_DATA2 /dir1/dir2/master.data setenv LPI_Report /doc/reports/deptA/week23.rep In the second example, LPI_Report was used rather than LPI_FACTS, because of the TITLE option in that file's OPEN statement. Parent topic: Files Send feedback about this topic

1.13. Input and Output


Open PL/I provides two types of Input/Output processing: stream I/O and record I/O. Each type of I/O has its own statements, and each type operates on its own kind of files. Open PL/I can process more than 32,767 records per file and supports UNIX named pipes, which enables the reading and writing of massive data sets - greater than 2 GB something not normally permitted in UNIX I/O. A stream file is a sequence of characters organized into lines and pages. When reading or writing a file using stream I/ O, the data is treated as if it formed a continuous stream of ASCII characters. Stream files are written by PUT statements and are read by GET statements. A record file is a set of discrete records that are accessible either sequentially or by keys. When reading or writing a file using record I/O, only one record is processed upon the execution of the I/O statement. Record files are read and written by READ, WRITE, REWRITE, and DELETE statements. The following sections provide detailed information on the two types of input and output processing available through Open PL/I: stream I/O and record I/O.

Stream I/O Record I/O

Parent topic: Language Concepts Send feedback about this topic

1.13.1. Stream I/O


Stream I/O treats data in the external file as a stream of ASCII characters. In a stream I/O operation, a list of program variables is associated with actual input or output fields of data. Two forms of stream I/O statements exist:

List-directed stream I/O, as performed by the GET LIST and PUT LIST statements. Edit-directed stream I/O, as performed by the GET EDIT and PUT EDIT statements.

In both list-directed and edit-directed stream I/O, the files are written by the PUT statement and are read by the GET statement. In edit-directed stream I/O, data is transmitted to or from a stream file under the control of a format-list. In
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (44 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

list-directed stream I/O, data is transmitted to and from the stream file without a format-list. In edit-directed stream I/O, format-lists can be part of the GET or PUT statement or can be given by a FORMAT statement. Execution of a GET or PUT statement transmits data from or to the current line of a stream file and may not consume or produce an entire line of the stream file. Several PUT statements can be used to build a given line, or a single PUT statement can be used to output several lines. Similarly, several GET statements can read values from a given line, or a single GET statement can be used to read one or more lines. Lines read from a disk file are not modified by Open PL/ I in any way; however, lines read from all other devices have trailing blanks removed and have one blank appended to the end of each line that is read by a GET statement. This blank ensures that a field typed at the beginning of a line is not appended to a field typed at the end of the previous line. Each stream file has an associated line size that is determined when the file is opened. Lines of an output file contain n characters, where n is the line size of the file. (For more information, see the discussion of the LINESIZE option in the section Stream File Attributes.) A shorter line can be created by using the SKIP option on a PUT statement, as shown in the following example of a list-directed stream I/O statement. The shorter lines are padded to the right with blanks to obtain a length of n characters. For example: PUT FILE(F) SKIP LIST(A,B,C); PUT FILE(F) SKIP; In this example, the current line (consisting of data previously output) is output and one or more new lines containing the values of A, B, and C are created. The second PUT statement forces the last line containing A, B, and C to be output and starts a new line. The SKIP option is always executed before any new data is transmitted. On input, each line can be of any length up to the value of the line size. Execution of a GET statement reads from the current line until a new line is reached, the new line is ignored, and execution continues reading values and lines until the list of variables has been read. A SKIP option can be used to force a new line to be read prior to reading any values, as shown in the following example. GET FILE(F) LIST(A,B,C); GET FILE(F) LIST(D); GET FILE(F) SKIP LIST(X,Y); In the previous example, A, B, and C are read from the current line or from as many lines as are necessary. D is read from the same line as C, unless C happened to be the last value on its line. The SKIP option skips to a new line and consequently ignores any values remaining on the line after the value received by D. X and Y are read from the line that is current after the SKIP option, as well as any additional, necessary lines. The PAGE option can be used in a PUT statement to begin a new page prior to transmitting any values, as shown in the following example. PUT FILE(F) PAGE LIST(A,B,C); For a complete discussion of GET, PUT, and FORMAT statements, see the chapter Statements. Note: Standard PL/I, in a stream file, does not provide a way to read a variable-length input line from the current position to a newline indicator. Open PL/I provides two nonstandard methods to read all characters from current position to new line into a character varying variable: a READ statement and an edit-directed GET statement. To read a variable-length line with a GET statement, you must use an A-format without a field width.

List-Directed Stream I/O

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (45 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Data-Directed Stream I/O Edit-Directed Stream I/O Terminal I/O on a Stream File

Parent topic: Input and Output Related information Stream File Attributes Statements READ A-Format

Send feedback about this topic

1.13.1.1. List-Directed Stream I/O


Values transmitted by list-directed stream I/O are separated by blanks or commas on input and by blanks on output. Each value is transmitted in a readable format determined by the value's data type. In a GET LIST operation, Open PL/I automatically converts ASCII input data to the data types of the variables specified in the GET LIST statement. In a PUT LIST operation, Open PL/I converts a computational expression to its ASCII equivalent for output. The following example of simple terminal output demonstrates list-directed stream I/O: PUT LIST(A,B); In this example, if A is an integer declared fixed binary whose current value is -75, and B is a character-string declared character(5) whose current value is HAT , the example produces:

in the current output line of file F. The field -75 is produced by converting the fixed binary(15) integer to a character-string. The many blanks allow for the maximum possible value, plus sign and decimal point and leading 0 for fractional values, as explained in the section Arithmetic to Character-String Conversion in the chapter Data Type Conversions. A single blank separates the value of A from the value of B. The last blank separates B from the next field. For input, list-directed I/O considers each blank or comma as a field terminator. Excess commas are not allowed. Excess blanks within a field to be assigned to an arithmetic variable are ignored. Such fields must simply contain a valid constant, as could be written in the text of a program. A field to be assigned to a character-string variable may contain a character-string constant, as written in the text of a program, or it may contain a sequence of any characters. In the latter case, the sequence begins with the first nonblank character in the field and ends with the character immediately preceding the next comma or blank, as shown in the following example of a GET LIST operation. Note that character sequences containing blanks or commas that are to be treated as a unit must be enclosed in single quotation marks ("). For example:

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (46 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

GET FILE(F) LIST(A,B); In this example, if A is fixed binary(15) and B is character(5), the following lines have the indicated effect on the values of A and B.

Line

5 -4 5 -4 5 abc-4

Parent topic: Stream I/O Related information Arithmetic to Character-String Conversion

Send feedback about this topic

1.13.1.2. Data-Directed Stream I/O


Data-directed stream I/O is similar to list-directed stream I/O. The difference is that with data-directed stream I/O, the actual Open PL/I program names of the data values are included in the stream file along with the values. For example, if your program contains the structure: DECLARE 1 STRUC, 2 NUM(2) FIXED BIN(15) INIT(255,-432), 2 TEXT CHAR(4) INIT('abcd'); and outputs this data with a PUT DATA statement, the characters emitted for STRUC would be: STRUC.NUM(1) 255 STRUC.NUM(2)= -432 STRUC.TEXT='abcd' ;

Each data value is preceded by the fully-qualified and specifically subscripted PL/I program name of that data value, as shown. The values themselves are formatted as they would be by a PUT LIST statement, except that character values are always enclosed in quotes. Parent topic: Stream I/O Send feedback about this topic

1.13.1.3. Edit-Directed Stream I/O


Values transmitted by edit-directed stream I/O are transmitted into fixed-length fields whose length and content are controlled by data-formats. Data-formats specifically control the type of conversion to be performed and the number of characters or digits in an input or output field. Each data-format corresponds to an element of the GET or PUT statement's value list and causes that value to be converted and transmitted. For example:
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (47 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

PUT FILE(F) EDIT(A,B) (F(7,2),A(6)); In this example, if A is declared fixed binary(15) and has a current value of -45, and B is declared character(4) and has a current value of HAT , the following is written into the current line of file F.

Control formats can be used to force new lines and skip parts of lines, as shown in the next example. If there are more format items than values to be transmitted in the statement's I/O list, the extra format items are ignored. For example: PUT FILE(F) EDIT(A,B) (X(3),F(7,2),SKIP,X(4),A(6),SKIP); Using the same values of A and B as in the previous example, the above statement produces the following:

In this example, the first line is placed at the end of the current line, and the second line starts a new output line. The PUT statement does not start another new line, because B was the last item output; hence, the PUT statement terminated before the second SKIP was executed. Edit-directed input requires that each input line be described precisely by the controlling format. If the current input line contains fewer characters than are required to satisfy the format, additional lines are read until the format is satisfied, as shown in the following example. GET FILE(F) EDIT (X) (A(80)); In this example, if X is declared as character(100) and the current line contains only 60 characters, the 60 characters are read, a new line is read, processing advances to the next line, and 20 additional characters are read from that line. The 80 characters thus read are then assigned to X, and 20 blanks are used to pad the value of X on the right. Parent topic: Stream I/O Send feedback about this topic

1.13.1.4. Terminal I/O on a Stream File


If a terminal device is opened as a stream file, the file is unlike any other stream file in the following respects:

Each PUT statement transmits data to the device without waiting for the line to be filled. A GET statement resets the current column position used by subsequent PUT statements.

Stream File Attributes Print Files

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (48 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Parent topic: Stream I/O Send feedback about this topic

1.13.1.4.1. Stream File Attributes


The following attributes are appropriate for use with stream files. Some may be used in either the DECLARE statement for the file constant or in the OPEN statement, others only in the OPEN statement.

Attribute

Permitted in Specification

STREAM INPUT OUTPUT PRINT LINESIZE PAGESIZE TITLE

DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN OPEN OPEN OPEN

The use of PRINT implies STREAM OUTPUT. If neither INPUT, OUTPUT, nor PRINT is specified, INPUT is assumed. LINESIZE and PAGESIZE can be used only for PRINT files. If neither STREAM nor RECORD is specified, the default is STREAM. (See the section Record I/O.) STREAM and RECORD are mutually exclusive, as are INPUT and OUTPUT. If attributes are specified both in the DECLARE statement and the OPEN statement for a file, the attributes used are the combination of those in the two statements. The combination may include only one of each mutually exclusive set. The TITLE option is used to associate a file as declared in the PL/I program with a file or device as known to the operating system. In the following examples of OPEN statements, the quoted text in the TITLE options specifies the system filename or device name to be used in I/O operations with the opening of the PL/I file indicated by the FILE option. If the TITLE option is not specified in an OPEN statement, the declared name of the file constant is used as the default title. The LINESIZE option is used in an OPEN statement to specify the maximum number of characters that can be output in a single line for a STREAM file. If no line size is specified, a default line size is assumed. For more information on LINESIZE, see the section PUT in the chapter Statements. The LINESIZE option can appear in the OPEN statement only and is valid only with STREAM OUTPUT files. During output, a newline will be inserted whenever the column position equals (LINESIZE+1). The SKIP or LINE options with a PUT statement cause a newline character to be inserted and the column position to be reset. The COLUMN format with a PUT EDIT statement may cause a newline to be inserted. The default may vary according to the file name or device. In Open PL/I, the default value of the LINESIZE option is 120. The PAGESIZE option is used in an OPEN statement to specify the maximum number of lines that can be written to a print file without signaling the ENDPAGE condition. If no page size is specified, a default page size is supplied. In Open PL/I, the default value of the PAGESIZE option is 60.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (49 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

If a GET or PUT statement is executed on a file that has not been opened, the file is implicitly opened as a STREAM file using the declared name of the file constant as the title. A file so opened by a GET statement is opened as an INPUT file, one so opened by a PUT statement is opened as an OUTPUT file. You can add text to any existing stream file (any ASCII file) by using the -APPEND option in the TITLE option of the OPEN statement. Thus, if the file you wish to append to is named "logfile," open it with the following TITLE option: TITLE('logfile -APPEND') Any subsequent PUT statements to this file simply append their output to the end of the file.

Examples:

Parent topic: Terminal I/O on a Stream File Related information Record I/O PUT TITLE Options

Send feedback about this topic

1.13.1.4.1.1. Examples:
OPEN FILE(F) OUTPUT TITLE('thedata'); OPEN FILE(TTY) TITLE('CONSOLE') STREAM INPUT; OPEN FILE(PTR) TITLE('LPT1') STREAM OUTPUT PRINT LINESIZE(132) PAGESIZE(60); OPEN FILE(MSG_FILE) INPUT; /* The default title is 'MSG_FILE' */

Parent topic: Stream File Attributes Send feedback about this topic

1.13.1.4.2. Print Files


An output stream file opened with the PRINT attribute indicates that the file is a print file. When a file is declared as a print file, the LINESIZE and PAGESIZE options may be specified at file opening to designate the maximum width of an output line and the maximum number of lines per page. The current line number and current page number of the print file can also be accessed using the PAGENO and LINENO built-in functions.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (50 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

The LINENO built-in function allows you to access the current line number of an output stream file opened with the PRINT attribute. Each time a line is written to the output stream, the line number is incremented by one. Each new line is initially positioned so that the next item is written to column 1 of the line. The PAGENO built-in function lets you read the current page number of an output stream file opened with the PRINT attribute. The current page number can be set using the PAGENO pseudo-variable. The ENDPAGE condition is signaled when the line to be written has a line number that is the page size plus one, or when a SKIP option positions the file to (or past) page size + 1. Each time a new page is written, the line number is reset to one and the page number is incremented by one. If an ON-unit for the ENDPAGE condition does not write a new page, the line number is allowed to increase indefinitely until a new page is written. The ENDPAGE condition is signaled only when the line to be written has a line number that is one greater than the page size. A new page is written only by a PAGE option of a PUT statement, by a PAGE format-item, and by the default ON-unit for the ENDPAGE condition. In Open PL/I, tab stops are set every eight columns for a stream file that has the PRINT attribute. Parent topic: Terminal I/O on a Stream File Send feedback about this topic

1.13.2. Record I/O


In Record I/O, file data is treated in terms of records. Record files are used with the READ, WRITE, REWRITE, and DELETE statements. Execution of one of these statements transmits one record to or from the file and updates the current position of the file. A record is a contiguous set of bytes of data in the file. The records of the file may all be of the same fixed length, as specified when the file is created, or they may be of varying lengths. Certain files with variable-length records require that a maximum length be specified when the file is created. The data bytes that comprise a record file may be ASCII characters, but they may also be any kind of binary data, including being paired as halfwords, grouped as binary fullwords or double words, grouped as packed-decimal strings, or considered as bit fields of any length. Record files may be keyed or not. If a record file does not have keys, its records can be accessed only in sequential order as they exist in the file, one after the other from the beginning of the file to the end. Open PL/I supports two keyed access methods: indexed (VSAM) I/O, which is based on character-string keys, and relative record I/O, which is based on integer record numbers.

Record File Attributes Consecutive Record I/O Indexed Record I/O Relative Record I/O REGIONAL(1) Record I/O

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (51 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

TITLE Options

Parent topic: Input and Output Send feedback about this topic

1.13.2.1. Record File Attributes


The following attributes are appropriate for use with record files. Some may be used in either the DECLARE statement for the file constant or in the OPEN statement, others only in the OPEN statement. Some attributes, if present, imply the presence of certain others.

Attribute

Permitted in Specification

Implied

RECORD INPUT OUTPUT UPDATE SEQUENTIAL KEYED DIRECT ENVIRONMENT TITLE

DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE or OPEN DECLARE OPEN RECORD RECORD RECORD RECORD KEYED

If neither INPUT, OUTPUT, nor UPDATE is specified, INPUT is assumed. If neither SEQUENTIAL nor DIRECT is specified, SEQUENTIAL is assumed. If neither STREAM nor RECORD is specified, the default is STREAM. (See the section Stream I/O.) The following sets of attributes are mutually exclusive:

STREAM and RECORD INPUT, OUTPUT, and UPDATE SEQUENTIAL and DIRECT

If attributes are specified both in the DECLARE statement and the OPEN statement for a file, the attributes used are the combination of those in the two statements. The combination may include only one of each mutually exclusive set. The TITLE option is used to associate a file as declared in the PL/I program with a file as known to the operating system. In the following examples of OPEN statements, the quoted text in the TITLE options specifies the system filename to be used in I/O operations with this opening of the PL/I file indicated by the FILE option. If the TITLE option is not specified in an OPEN statement, the declared name of the file constant is used as the default title. Examples:
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (52 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

OPEN FILE(F) RECORD OUTPUT TITLE('thedata'); OPEN FILE(F) RECORD INPUT; /* The default title is 'F' */ If a READ, WRITE, REWRITE, or DELETE statement is executed on a file that has not been opened, the file is implicitly opened as a RECORD file using the declared name of the file constant as the title. The attributes assigned to the file implicitly opened depend on the I/O statement used, as indicated below:

Record I/O Statement

Assigned Attributes

READ WRITE REWRITE DELETE

RECORD INPUT RECORD OUTPUT RECORD UPDATE RECORD UPDATE

Record input and output operations are restricted to files opened with certain attributes. These restrictions are shown in the following table:

File Attributes

Permitted I/O Operations

INPUT OUTPUT UPDATE

READ WRITE READ, WRITE, REWRITE, DELETE

If a file opened for INPUT or UPDATE does not exist, an error is signaled. If a file opened for OUTPUT does not exist, a file is created. If the file has been opened as DIRECT or KEYED SEQUENTIAL, a keyed file is created; otherwise, a non-keyed file is created. If a file opened for OUTPUT already exists, it is deleted and a new file is created. However, if the -APPEND option is specified in opening the file, an existing file can be opened for OUTPUT. You can add records to an existing record file by using the -APPEND option in the TITLE option of the OPEN statement. Thus, if the file you wish to append to is named "logfile," open it with the following TITLE option: TITLE ('logfile -APPEND') Any subsequent WRITE statements to this file simply append their output to the end of the file. A REWRITE statement replaces an existing record in an UPDATE file with a new record. A DELETE statement basically removes an existing record from an UPDATE file. A WRITE to an existing record and a READ from a nonexistent record are not allowed. A WRITE to a record past EOF will append the record to the end of the file. A DELETE or REWRITE of a nonexistent record signals a KEY condition. (For further information, see the description of KEY in the section ON in the chapter Statements.) Record I/O statements copy the storage of a variable to or from a record in a file (except in the case of READ

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (53 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

operations using locate mode I/O, see below). No conversion is performed and no check is made to ensure that the data being read is of the proper type to store into the variable. The variables used in INTO or FROM options cannot be unaligned bit strings or structures consisting entirely of unaligned bit strings, because such variables normally share a portion of their storage with other members of the same array or structure. Also, an expression cannot be used in a FROM or INTO option. Note: Structures with the UNION attribute cannot be used as variables in READ, WRITE, PUT, and GET statements. READ operations can be performed in two "modes": move mode and locate mode. A READ statement that specifies the INTO option causes the input data to be stored directly into the variable referenced by the INTO option. This is called a "move mode" READ. A READ statement that specifies the SET option instead of the INTO option causes the input data to be stored in an unnamed storage buffer and causes the address of this buffer to be assigned to the pointer variable referenced by the SET option. This is called a "locate mode" READ. A complete discussion of record I/O statements is found in the chapter Statements. Examples: READ FILE(CUSTOMERS) KEY(CUST_ID) INTO(CUST_RECORD); PUT SKIP LIST(CUST_RECORD.NAME); READ FILE(CUSTOMERS) KEY(CUST_ID) SET(CPTR); PUT SKIP LIST(CPTR->BASED_RECORD.NAME);

Parent topic: Record I/O Related information Stream I/O TITLE Options ON Statements

Send feedback about this topic

1.13.2.2. Consecutive Record I/O


A record file without keys is called a consecutive file. The records of such a file can be read only in the same sequential order in which they were written. Thus, a consecutive file can be read only one record after the other, starting with the first record in the file. A record of a consecutive file can be rewritten, but only immediately after it has been read. A consecutive file is declared by including the CONSECUTIVE option of the ENVIRONMENT attribute. For example, DECLARE ULOG RECORD OUTPUT FILE ENVIRONMENT(CONSECUTIVE RECSIZE(130)); In this example the RECSIZE option causes all records to be of length 130 bytes. If RECSIZE is omitted, variable length records may be written. In the latter case, there is no information automatically recorded in the file to indicate the length of the records. A program reading the file must have the ability to know how many bytes to read with each READ statement.
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (54 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Example: CONFILE: PROCEDURE OPTIONS(MAIN); DECLARE TEST RECORD OUTPUT FILE ENV(CONSECUTIVE); DECLARE REC1 CHAR(5) INIT('AAAAA'); DECLARE REC2 CHAR(10) INIT('BEEBBBBBBB'); OPEN FILE(TEST) TITLE('testdata'); WRITE FILE(TEST) FROM(REC1); WRITE FILE(TEST) FROM(REC2); WRITE FILE(TEST) FROM(REC1); CLOSE FILE(TEST); END CONFILE; The file testdata resulting from this program will contain the following 20 bytes: AAAAABBBBBBBBBBAAAAA Note: Open PL/I has an older method of accomplishing the same thing. It is done by using the TITLE option of the OPEN statement rather than the ENVIRONMENT attribute of the DECLARE statement. The following illustrates the old method. DECLARE RECORD TEST OUTPUT FILE; OPEN FILE (TEST) TITLE ('testfile -SAM');

Parent topic: Record I/O Related information TITLE Options

Send feedback about this topic

1.13.2.3. Indexed Record I/O


Open PL/I's indexed I/O, also called VSAM (Virtual Storage Access Method), involves the use of character-string keys that are stored in the records of the file. Every record has a key, and the keys are ordered lexicographically in an index that is associated with the file. The records can be accessed randomly by specifying the key of the desired record, or they can be accessed sequentially according to the order of the keys, or they can be accessed by a combination of these methods, as illustrated in the following table:.

File Attributes

Permitted Access

SEQUENTIAL

SEQUENTIAL only

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (55 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

DIRECT KEYED SEQUENTIAL

KEYED only SEQUENTIAL and/or KEYED in combination

An INDEXED (equivalently, VSAM) file is declared by including either the INDEXED or the VSAM option of the ENVIRONMENT attribute. For example, DECLARE MASTER RECORD OUTPUT FILE ENVIRONMENT(VSAM KEYLOC(1) KEYLENGTH(12) RECSIZE(130)); The KEYLOC option specifies the byte position of the first byte of the key in the records, counting the first byte as KEYLOC(1). The KEYLENGTH option specifies the number of characters in the key. RECSIZE specifies the record length or, in the case of a file of variable-length records, it specifies the maximum record length. Actually, it is necessary to specify RECSIZE, KEYLOC, and KEYLENGTH for a file only when it is created. Programs that read or update an existing indexed file do not need to include these options, although they may. Open PL/I can determine these characteristics from an existing file. If you are using full IBM mode, file header information is used when opening a VSAM file for output, rather than requiring you to specify RECSIZE, KEYLOC, or KEYLENGTH with the ENVIRONMENT attribute. There are a number of options that can be specified with the ENVIRONMENT attribute. These options are described in the table below. This table also lists a number of options that are not needed or not supported in Open PL/I, but which a user may expect to find based on experience with other compilers.

Option

Description

ASCII BKWD

The ASCII option is assumed in Open PL/I. Specifies backward processing for indexed files read in the SEQUENTIAL mode; that is, sequential processing will start with the current record (or last, by default) in the file and proceed to previous records. The BUFFERS option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFOFF option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFND option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFNI option is not needed in Open PL/I. If it is used, the Compiler ignores it. The BUFSP option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies a file with consecutive organization. For related information, see the description of the -defext compiler option in your Open PL/I User's Guide. The CTLASA option is ignored. The CTL360 option is not implemented in Open PL/I. If it is used, the Compiler issues a warning.

BUFFERS BUFOFF BUFND BUFNI BUFSP CONSECUTIVE CTLASA CTL360

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (56 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

F | FB | FS | FBS GENKEY

Specifies record format, where F = fixed length, B = blocked, and S = standard. Open PL/I treats any such specification as though it were F alone fixed length. Specifies a generic key, a character string that is a prefix of a key. A READ with a KEY clause returns the first record whose key is greater than or equal to the string specified by the KEY clause. A subsequent sequential READ (no KEY clause) will return the next record greater than the current record. The INDEXAREA option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies a file with indexed organization. For related information, see the description of the -defext compiler option in your Open PL/I User's Guide. Specifies the length, n, of the embedded key for indexed files. KEYLENGTH can be specified only when INDEXED or VSAM is specified. Specifies the starting location of an embedded key in a record. n must be within the limits: 1 n recordsize keylength + 1. The default KEYLOC value is 1. KEYLOC can be specified only when INDEXED or VSAM is specified. Note: Be sure that KEYLOC considers the 2-byte prefix generated by specification of the SCALARVARYING option.

INDEXAREA(n) INDEXED KEYLENGTH(n) KEYLOC(n)

LEAVE MINRECSIZE(n)

The LEAVE option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies the minimum record length, n. n must be an integer. This option allows for better disk space utilization. The MINRECSIZE option is required with V (variablelength) record formats. It is ignored for F (fixed-length) record formats. The values specified for the KEYLOC and KEYLENGTH options must be within the value specified by the MINRECSIZE option. For more information on the MINRECSIZE option, see below. The NCP option is not applicable in Open PL/I. Open PL/I treats INDEXED files the same as VSAM files. The NOWRITE option is not needed in Open PL/I. If it is used, the Compiler ignores it. The PASSWORD option is not implemented in Open PL/I. If it is used, the Compiler issues a warning. Specifies the maximum record length, n. n must be an integer.

NCP(n) NOWRITE PASSWORD(pwd) RECSIZE(n)

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (57 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

REGIONAL(1 | 2 | 3)

The REGIONAL(1) option specifies files whose records are identified by their region numbers. The REGIONAL(2) and REGIONAL(3) options are not implemented in Open PL/I. If they are used, the Compiler flags it as an error.

REUSE SCALARVARYING

The REUSE option specifies that an OUTPUT file associated with a VSAM data set is to be used as a work file. . Used for the input and output of varying length records. SCALARVARYING enables the recognition of a two-byte prefix that specifies the current length of the records. Note: Be sure that KEYLOC considers the 2-byte prefix generated by specification of the SCALARVARYING option.

SIS SKIP TP(MIR) TRKOFL U | D | DB V | VB | VS | VBS VSAM

The SIS option is not needed in Open PL/I. If it is used, the Compiler ignores it. The SKIP option is not needed in Open PL/I. If it is used, the Compiler ignores it. The TP(MIR) option is not implemented in Open PL/I. If it is used, the Compiler flags it as an error. The TRKOFL option is not needed in Open PL/I. If it is used, the Compiler ignores it. Specifies record format. Open PL/I treats any such specification as though it were F fixed length. Specifies record format, where V = variable length, B = blocked, and S = spanned. Open PL/I treats any such specification as though it were V. Specifies files organized for the virtual storage access method (VSAM). For related information, see the description of the -defext compiler option in your Open PL/I User's Guide.

A random access read of a record in an indexed (VSAM) file opened with the INPUT or UPDATE attribute is accomplished by a READ statement that includes the KEY option. For example, READ FILE(PARTS) INTO(PART_REC) KEY(PART_NUM); A sequential read reads the next record of the file after the last one read using the key ordering or the first record of the file, if no record has previously been read. For a sequential READ statement, the KEY option is omitted. If a record has previously been read from a file opened with the UPDATE attribute, and no other intervening I/O operation has been performed, a REWRITE without key may be executed. In this case, the previously read record is overwritten with the new value. For example, READ FILE(PARTS) INTO(PART_REC) KEY(PART_NUM); PART_REC = NEW VALUE; REWRITE FILE(PARTS) FROM(PART_REC); However, a record of an indexed file can be randomly updated by specifying the KEYFROM option in the REWRITE statement. For example,
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (58 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

REWRITE FILE(PARTS) FROM(PART_REC) KEYFROM('12XJ04'); If an indexed file has been opened with the OUTPUT or UPDATE attribute, a WRITE statement using the KEYFROM option can be used to add new records to the file. The WRITE statement without KEYFROM is used to sequentially add new records to a file. The DELETE statement can be used to remove records from an indexed file opened with the UPDATE attribute. The KEY option must be used to delete a record. All keys used in an indexed (VSAM) file must by of type CHARACTER. If a KEY or KEYFROM option references a value that is not of type CHARACTER, the value is converted to CHARACTER before the I/O operation begins. Note that keys of type PICTURE are converted to CHARACTER without any actual change in the key contents. (See the chapter Data Type Conversions.) An indexed (VSAM) file can have either fixed-length or variable-length records. The records are fixed-length if the F option is used with the ENVIRONMENT attribute when the file is created; they are variable-length if the V option is used. (See the table above.) If neither F nor V is specified, F is assumed. In a fixed-length record file, all records must have the same length, which is the length specified by the RECSIZE option of the ENVIRONMENT attribute when the file was created. For a variable-length record file, RECSIZE specifies the maximum record length that is permitted in the file. The MINRECSIZE option must also be specified for a variablelength record file. This value specifies the minimum length that all records in the file must have. The keys of the file must be contained within this minimum portion of the file. The SCALARVARYING option specifies that there is a two-byte prefix on all records in the data file. A user must take this into account when specifying the KEYLOC value. The KEYLOC value is the absolute byte position of the record starting at 1. This option can be used on either F or V record formats. It allows for more general use of character varying records in I/O statements, although character records can also be transmitted. When a character varying item is used in a WRITE or REWRITE statement, the two-byte prefix is retained with the record as it gets written out to the data file, if the SCALARVARYING option is set. Without the SCALARVARYING option, the prefix is not written; in this case, the remainder of the record is undefined beyond its current length. When a character record is written, a prefix will be added if SCALARVARYING option is set. The SCALARVARYING option lets you write and read records smaller then your max record size, without getting the RECORD condition. It also is useful when doing locate mode I/O. When setting KEYLOC, it is very important to "compensate" for the two-byte prefix when the SCALARVARYING option is used. The use of V type records provide a way to transmit partial records. Open PL/I does not require control bytes in the record for this support. The run-time system will automatically retain information concerning the number of bytes transmitted. Since no control information is needed in the record, the user should not change KEYLOC based on the record type. Only the SCALARVARYING option has impact on the KEYLOC location. Although the PL/I language does not provide a mechanism by which multiple keys can be specified for a file, Open PL/ I does provide a means for accessing data via multiple keys. After an indexed file has been created using one key (which is called the primary key), you can use the utility Ipivsam to add additional indexes (that is, keys) to the file. In the PL/I program each different key version of the data must be declared as a separate file. However, all of these declared files can actually be referencing the same set of data. For example, DECLARE EMPFILE1 RECORD UPDATE FILE ENV(VSAM KEYLOC(1) KEYLENGTH(6) RECSIZE(145)); DECLARE EMPFILE2 RECORD UPDATE FILE ENV(VSAM KEYLOC(31) KEYLENGTH(3) RECSIZE(145) GENKEY); DECLARE 1 EMP_ 2 EMP_ID (CHAR(6), 2 NAME (CHAR(24),

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (59 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

2 DEPARTMT ...

(CHAR(3),

OPEN FILE(CUSTFILE1) TITLE('employee'); OPEN FILE(CUSTFILE2) TITLE('employee'); /* same file, different key */ The following example program illustrates the use of the ENVIRONMENT variable and its options for I/O on a file with VSAM organization. /* Example of VSAM I/O */ TEST: PROCEDURE OPTIONS(MAIN); %REPLACE TRUE BY '1'B; %REPLACE FALSE BY '0'B; DECLARE DB FILE ENV(VSAM KEYLOC(21) KEYLENGTH(120) RECSIZE(244)); DECLARE DBG FILE ENV(INDEXED GENKEY KEYLOC(21) KEYLENGTH(120) RECSIZE(244)); DECLARE 1 DB_RECORD, 2 HEADER CHAR(20), 2 DBKEY CHAR(120), 2 STUFF CHAR(100), 2 NUMBER FIXED BIN(31); DECLARE I FIXED BIN(31); DECLARE CS CHAR(26) STATIC INIT('THEQUICKBROWNFXJMPSVLAZYDG'); DECLARE C(26) CHAR DEFINED(CS); DECLARE LETTERS CHAR(30); /* CREATE DB */ OPEN FILE(DB) RECORD KEYED SEQUENTIAL OUTPUT TITLE('MYFILE1'); HEADER = 'DATA RECORD HEADER'; STUFF = COPY('ABCDE',20); DO I = 1 TO 26; NUMBER = I; DBKEY = '@'||C(I) ||COPY('@',118); WRITE FILE(DB) FROM(DB_RECORD) KEYFROM(DBKEY); END; CLOSE FILE(DB); /* TRY A GENERIC READ THEN MOVE SEQUENTIALLY THRU THE FILE */ OPEN FILE(DBG) RECORD KEYED SEQUENTIAL INPUT TITLE('MYFILE1'); ON ENDFILE(DBG) GOTO EXIT_1; READ FILE(DBG) KEY('@') INTO(DB_RECORD); LETTERS = SUBSTR(DBKEY,2,1); DO WHILE(TRUE); READ FILE(DBG) INTO(DB_RECORD); LETTERS = TRIM(LETTERS) ||SUBSTR(DBKEY,2,1); END;
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (60 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

EXIT_1: CLOSE FILE(DBG); PUT EDIT(LETTERS)(A); IF LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' THEN PUT SKIP LIST('TEST PASSES'); ELSE PUT SKIP LIST('TEST FAILS'); PUT SKIP; END TEST;

Parent topic: Record I/O Related information Open PL/I User's Guide Data Type Conversions

Send feedback about this topic

1.13.2.4. Relative Record I/O


Open PL/I also provides an I/O method for accessing consecutive files by a numeric key representing the relative record numbers of the records in the file. This is called relative record I/O. It can be used only with files of fixed-length records, and it cannot be used with indexed (VSAM) files. Relative record I/O files are regarded as keyed files, but the keys are not stored in the file. They are just the ordinal numbers of the records in the file. The keys must be positive integers. Any value used in a KEY or KEYFROM option of an I/O statement must be an integer or be capable of conversion to an integer. The ENVIRONMENT attribute is not used in the declaration of a relative record I/O file. Instead, such a file is specified by using an extension of the TITLE option of the OPEN statement. The format of this TITLE option is as follows: TITLE('filename -DAM n') where n is the length of the records in the file. The length n includes two bytes that are normally added to the beginning of each record. This halfword is used to record special information about the file.(See the section TITLE Options.) In general, the same set of PL/I I/O operations can be used with relative record I/O files as with indexed files. A relative record I/O file can be created using an additional extension in the TITLE option, as follows: TITLE('filename -DAM n -NOSIZE') The -NOSIZE option indicates that the two-byte special field is not to be added to the data records. If -NOSIZE is specified for a file, the DELETE statement cannot be used with the file. Parent topic: Record I/O Related information TITLE Options

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (61 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Send feedback about this topic

1.13.2.5. REGIONAL(1) Record I/O


A REGIONAL(1) file does not have keys recorded in the records. Instead, each record is identified by its region number, which is an unsigned integer. The keys for a REGIONAL(1) file may be character strings consisting only of decimal digits, possibly preceded by leading spaces (which are interpreted as zeros), or the keys can be of integer type. A REGIONAL(1) file contains data records and dummy records. A dummy record is identified by having a first byte with the hex value FF. Dummy records represent records that have been deleted or whose region numbers have been skipped over when the file was first created. You can also create them explicitly by writing a record whose first byte has the value hex FF. Dummy records are not ignored when the REGIONAL(1) file is read. An Open PL/I program reading a REGIONAL(1) file must be designed to deal with dummy records. You can replace dummy records with valid data records. You can create a REGIONAL(1) file only by use of DIRECT OUTPUT mode using keyed WRITE statements. The records must be written in ascending region number order, but you may skip over region numbers. When a region number is skipped, a dummy record is written in its place. The KEY condition is raised if you attempt to write records other than in increasing sequence or if you attempt to write a record with a duplicate key. An existing REGIONAL(1) file can be accessed in SEQUENTIAL INPUT or UPDATE mode, or in DIRECT INPUT or UPDATE mode. (Opening the file in OUTPUT mode causes the existing file to be overwritten.) If a REGIONAL(1) file is opened for SEQUENTIAL access (INPUT or UP_ DATE), the records are retrieved in ascending order of their region numbers. Dummy records are retrieved as well as valid data records. With SEQUENTIAL INPUT, you can read all records of the file in ascending region number order; with SEQUENTIAL UPDATE, you can so read all records and update those you choose (including changing dummy records to valid data records, and valid data records to dummy records). The rules for sequential READ and REWRITE for REGIONAL(1) are the same as for CONSECUTIVE files. A REGIONAL(1) file can be opened for INPUT or UPDATE in DIRECT access mode, in which case keyed READ, WRITE, REWRITE, and DELETE statements can be used. READ accesses dummy records as well as valid data records. WRITE and REWRITE are equivalent; either replaces an existing record (data or dummy record) with a replacement record (again, either a data or a dummy record). DELETE converts the record with the specified region number into a dummy record.

Example of REGIONAL(1) I/O

Parent topic: Record I/O Send feedback about this topic

1.13.2.5.1. Example of REGIONAL(1) I/O


/* This program creates and updates a REGIONAL(1) file */ sample: procedure options(main); declare File1 file environment(regional(1) recsize(20));/*requires -defext declare Buffer char(20);

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (62 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

declare FirstByte char(1) defined(Buffer); declare Key char(4) varying; declare Eof bit; put skip list('Creating REGIONAL(1) file with records 1, 5 and 9.'); open file(File1) output; Buffer = copy('1',size(Buffer)); write file (File1) from(Buffer) keyfrom (1); Buffer = copy('5',size(Buffer)); write file (File1) from(Buffer) keyfrom (5); Buffer = copy('9',size(Buffer)); write file (File1) from(Buffer) keyfrom (9); close file(File1); open file(File1) update; on endfile(File1) Eof = '1'b1; Eof '0'b1; /* Initialize */ put skip list('Reading file and updating the even numbered records.'); read file(File1) into(Buffer) keyto(Key); do while (^Eof); if unspec(FirstByte) = 'FF'b4 then do; /* dummy record */ if (mod(fixed(Key,15),2) = 0) then do; /* change even number ones * Buffer = 'rewritten'; rewrite file(File1) from (Buffer); /* rewrite current record */ end; end; read file(File1) into (Buffer) keyto(Key); end; Eof = '0'b1; /* Reset */ put skip(2) list ('Reading and displaying all records in file.'); Key = '1'; read file(File1) into(Buffer) key(Key); /* direct read */ do while (^Eof); if unspec(FirstByte) = 'FF'b4 then put skip list(Key,'<dummy record>'); else put skip list(Key,Buffer); read file(File1) into(Buffer) keyto(Key); /* sequential read */ end; close file(File1); put skip; end sample; You can compile, link, execute, and display the output of the above sample program with the following commands: mfplx sample.pl1 -defext -o sample.out sample.out The output is as follows: Creating REGIONAL(1) file with records 1, 5 and 9. Reading file and updating the even numbered records. Reading and displaying all records in file. 1 11111111111111111111 2 rewritten
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (63 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

3 4 5 6 7 8 9

<dummy record> rewritten 55555555555555555555 rewritten <dummy record> rewritten 99999999999999999999

Parent topic: REGIONAL(1) Record I/O Send feedback about this topic

1.13.2.6. TITLE Options


Open PL/I supports a number of non-standard TITLE options that can be used to indicate the type of file being opened. These are as follows: -SAM [n] -DAM [n] -NOSIZE -APPEND [n] -DELABORT [n] where n is an integer indicating that the file has fixed-length records of length n bytes. These options are included in the operand of the TITLE option immediately following the filename and separated from it by one or more spaces, as shown in the following examples: TITLE('recfile.dat TITLE('keyfile -DAM') -SAM 80')

The -SAM and -APPEND options can be used with stream files, in which case the length, if specified, is ignored. -SAM is never required for stream files. -SAM [n] specifies that the file is a consecutive file. If n is specified when the file is created, the file is created with records of fixed length n. The maximum value for n is 131,017 bytes. If n is not specified when the file is created, records written to the file can be of any length and of varying lengths. If -SAM is used when opening a file for OUTPUT, if the file already exists, it is deleted and a new file is created. -DAM [n] specifies that the file is a relative record I/O file. If n is specified when the file is created, the file is created with records of fixed length n. If n is not specified when the file is created, the file is created as a variable-length record file. If -NOSIZE is not also specified, this length n includes the two bytes that are added as a halfword of length information at the beginning of each record. -NOSIZE can be used alone or in combination with -DAM [n]. It specifies that the length halfword is not included at the beginning of each record. If -NOSIZE is used without -DAM [n], -DAM is implied. -APPEND [n] has the same meaning as -SAM, except that when used in opening a file for OUTPUT, it causes an already existing file to be appended to rather than replaced. -DELABORT causes the file to be deleted when it is closed.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (64 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

If a file is opened for OUTPUT and none of these TITLE options is specified, and there is no ENVIRONMENT attribute in the file declaration, if the opening is for a DIRECT file, -DAM is assumed, and if the opening is not for a DIRECT file, -SAM is assumed. Parent topic: Record I/O Send feedback about this topic

2. Data Types

Introduction Arithmetic Data Picture Data Character-String Data Wide Character-String Data (UTF-16 Support) Bit-String Data Area Data Locator Data Label Data Entry Data File Data Arrays Structures Arrays of Structures Data Size and Alignment

Parent topic: Open PL/I Language Reference Manual Send feedback about this topic

2.1. Introduction
Each value has a data type that determines which operations can be performed on the value and the way in which the
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (65 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

value is represented in storage. Data types are declared for variables, function results, named constants (such as files), and external procedures. They are also used with the ENTRY attribute to describe the data type of each parameter of a procedure. Data types are declared using the following attributes:

Computational Data

Non-Computational Data

FIXED BINARY FIXED DECIMAL FLOAT BINARY FLOAT DECIMAL PICTURE CHARACTER CHARACTER VARYING WIDECHAR WIDECHAR VARYING BIT

POINTER LABEL ENTRY FILE OFFSET AREA

AREA

The attributes in the first column represent data items whose values can be manipulated by arithmetic or string operations and are therefore computational. The attributes in the second column refer to data used within a program for control structures and linkage and are therefore non-computational. The data type of a value produced by an expression is determined by the operands and the built-in functions within the expression. The data type of a constant is determined by the syntax of the constant. A variable capable of storing only one value, such as an integer or a character string, at any one time is called a scalar variable. An array variable is a collection of variables all of the same type. For example, an array might consist of 20 individual character strings. The variables contained in the array are called elements of the array. These elements all have the same name as the array. They are ordered by a numeric index, or perhaps several indices, and they are referenced by use of these indices. A structure variable is a collection of variables of arbitrarily mixed types. The variables contained in a structure are called members of the structure. The members each have their own name. A member may be referenced by its name alone, or its name may be qualified by the structure name to distinguish it from a member of another structure. A structure can contain subordinate structures as members, as well as array members and scalar members. Also, the elements of an array can be structures. This chapter discusses each data type, beginning with computational data types. Parent topic: Data Types Related information ENTRY Types of Operators Open PL/I Built-Ins
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (66 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Send feedback about this topic

2.2. Arithmetic Data


Each arithmetic value is characterized by a base (binary or decimal), a scale (fixed-point or floating-point), and a precision (the number of digits in the value). These three properties collectively constitute the data type of the arithmetic value. The data type of arithmetic values is expressed using the following attributes:

FIXED BINARY(p) and FIXED DECIMAL(p,q) for fixed-point data FLOAT BINARY(p) and FLOAT DECIMAL(p) for floating-point data

where p is the precision and q is the number of fractional digits in the precision. Each implementation of PL/I imposes limits on the maximum values of p and q, and these limits typically differ for each combination of base and scale. Refer to your Open PL/I User's Guide for information on the default precision and maximum precision for each arithmetic data type in Open PL/I.

Fixed-Point Binary Literals Floating-Point Binary Literals Fixed-Point Data Floating-Point Data

Parent topic: Data Types Send feedback about this topic

2.2.1. Fixed-Point Binary Literals


Fixed-point binary literals are treated the same way as fixed-point decimal literals. Examples of fixed-point binary literals are: 1000b, 1000.101B

Parent topic: Arithmetic Data Send feedback about this topic

2.2.2. Floating-Point Binary Literals


http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (67 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

The IBM compiler converts binary floating-point literals to short floating-point values if the precision is less than 21. However, Open PL/I ignores precision, and always converts the string to a floating-point decimal with the maximum permitted precision. Examples of floating-point binary literals are: 1000E201b, 1000.101E2B

Parent topic: Arithmetic Data Send feedback about this topic

2.2.3. Fixed-Point Data


Fixed-point numbers contain p digits. For fixed-point decimal numbers, q of those digits may be fractional digits. Fixedpoint binary numbers are always integers (q =0). For example: DECLARE K FIXED BINARY(15); DECLARE D FIXED DECIMAL(7,2); In this example, the values of K are fixed-point integers with 15 binary digits. Therefore, K can hold any value in the range -32768 to +32767 or -(2**15) to (2**15)-1. The values of D are fixed-point numbers with seven decimal digits, two of which are fractional digits. Therefore, D can hold any value in the range -99999.99 to +99999.99. Because most computers operate most efficiently with binary integers, fixed binary variables should be used whenever possible. The relative efficiency of fixed binary variables used as subscripts, string lengths, DO index variables, and so forth is very significant. Refer to your Open PL/I User's Guide for a description of the -Iongint compiler option, which alters the default precision of fixed binary variables from 15 to 31. Fixed decimal values generally require more bits of storage and are often more computationally complex than values represented in binary, but fixed decimal values are more efficiently converted to and from an external form (for example, at input and output). In certain instances, fixed decimal values may also be less prone to rounding error than their binary counterparts. An attempt to calculate a fixed decimal value too large to be supported results in a signal of the ERROR condition. An attempt to calculate a fixed binary value too large to be supported will not result in any error and may cause unexpected results. For rules on precision and scale, see the chapter Data Type Conversions. Operations involving both decimal and binary values always produce a binary result value. However, if the operation must yield a result that has a fractional part, the result is decimal. If a fixed-point value is converted to a character string or bit string, the length of the string is determined by the declared precision of the fixed-point value p. For a discussion of the conversion rules, see the chapter Data Type Conversions. Fixed-point values are never rounded unless explicitly rounded by the use of a built-in function. Assignment to a fixedpoint variable truncates excess low-order digits. All possible roundings can be performed by using the CEIL, FLOOR, TRUNC, or ROUND built-in functions. Fixed-point decimal values are always stored as an accurate representation of decimal fractions. A fixed-point decimal value of 10.50 is never represented as 10.49. Fixed-point constants are written as decimal numbers with or without a decimal point, as shown in the following examples:

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (68 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

5 4.5 4100.01 If a fixed-point constant contains a decimal point, it is considered to be a scaled fixed-point value and is stored and accessed like a fixed decimal variable. Fixed-point constants without a decimal point are integer constants and can be used safely in operations with any other arithmetic value, regardless of that value's base or scale. It is advisable to always write integer constants without a decimal point. The precision of a fixed-point constant is the number of digits in the constant. Parent topic: Arithmetic Data Related information Open PL/I User's Guide Data Type Conversions Open PL/I Built-Ins

Send feedback about this topic

2.2.4. Floating-Point Data


Floating-point data is used to represent values whose magnitudes are too great or too small to be represented by fixedpoint data. It may also be used to minimize precision loss in calculations where terms differ considerably in magnitude. Unexpected results may appear when using floating-point values. The limited precision of floating-point variables and the fact that they cannot precisely represent most fractional values combine to produce behavior in a program that may seem strange. Furthermore, the floating-point implementation on many machines carries more precision in intermediate results than is strictly required by the rules of PL/I. Also, floating-point variables and constants are usually limited to only one or two actual internal precision values. For example, most implementations of the IEEE floatingpoint standard allow only "short" (23-bit) and "long" (52-bit) floating-point values. Finally, precise results may vary depending on the level of program optimization. For example, consider the following program: SAMPLE: PROCEDURE OPTIONS (MAIN); DECLARE (F,G) FLOAT BINARY (23); F = 3111; G = .14; IF F + G ^= 3111.14 THEN PUT LIST ('UNEQUAL RESULT'); END SAMPLE; This program will actually print the UNEQUAL RESULT message when run on many machines, because the constant .14 and 3111.14 are not precisely representable as floating-point binary numbers. The assignment of .14 to G puts about 23 bits of precision of the constant into the variable. On most implementations, the sum is computed with an actual precision of 52 or more bits, preserving the 23 bits of precision that apply to the fractional part. However, that sum is being compared to the constant 3111.14. The constant will have 23 or 52 bits of precision. (In fact, a strict implementation of the rules of the language requires only that it have 20 bits of precision; for more information, see the chapter Data Type Conversions.) If 3111.14 is represented as a short floating-point number, 14 of the 23 bits of precision are taken up to represent 3111 and hence only 9 bits of the fraction appear in the constant. This will not
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (69 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

result in an equal comparison to the constant 3111.14. If the constant is a long floating-point number, 38 of the 25 precision bits will be fractional and the comparison will still fail. One attempt to fix this might be to change the program as follows: SAMPLE: PROCEDURE OPTIONS (MAIN); DECLARE (F, G, H) FLOAT BINARY (23); RESULT FLOAT BINARY (23) STATIC INITIAL (3111.14) F = 3111; G = .14; H = F + G IF H ^= 3111.14 THEN PUT LIST ('UNEQUAL RESULT') END SAMPLE; This appears to truncate the sum to a "real" 23 bits of precision and to compare it to a constant of known precision. This will normally work. However, in the presence of optimization, the value of F + G may be used without reducing its precision through storing it in H and then reloading it. Thus, as a general rule, comparing floating-point numbers for equality and inequality does not work reliably. Instead, check for equality using the following method: ABS(FIRST-SECOND) < EPSILON where the constant EPSILON must be chosen considering the goal of the application. Floating-point numbers consist of a mantissa m, a base b, and an exponent e. A floating-point number is represented in the following format: m*b**e The mantissa m is a fraction containing at least p digits. The value of b and the possible range of e are defined by each implementation (for information on this implementation, refer to your Open PL/I User's Guide); however, if the base is binary, m contains the equivalent of at least p binary digits, and if the base is decimal, m contains the equivalent of at least p decimal digits. For example: DECLARE X FLOAT BINARY(23); DECLARE Y FLOAT DECIMAL(7); In this example, the values of X are floating-point numbers whose mantissa contains the equivalent of at least 23 binary digits. The values of Y are floating-point numbers whose mantissa contains the equivalent of at least 7 decimal digits. The representation of floating-point values in storage also depends on the implementation. An implementation may represent the mantissa in any base that it chooses, provided that it contains an equivalent of at least p binary or p decimal digits. On some computers, decimal floating-point values are represented by using a decimal mantissa, while other implementations use a binary or hexadecimal mantissa for all floating-point numbers. Open PL/I represents floating-point decimal using a decimal mantissa and decimal exponent, and represents floatingpoint binary using a binary mantissa and binary exponent. For more information, refer to your Open PL/I User's Guide. Because floating-point values may be represented in either base, and because excess digits may be lost during calculations, floating-point values may be approximate. However, any integer value that is converted to floating-point and converted back to integer retains its original value. Likewise, the floating-point calculations of addition, subtraction, and multiplication, when performed on integer values, produce integer values.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (70 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Floating-point constants are written as fixed-point constants followed by an exponent, as shown in the following examples: 5E+02 4.5E1 100E-04 .001E-04 0E0 Floating-point constants have a decimal precision of p, where p is the number of digits in the fixed-point constant. For example, 4.5E1 has a precision of 2. When fixed-point constants such as 1.5 are used in operations with floating-point values, they should be written with an exponent to avoid run-time conversion of fixed-point decimal values to floating-point. If floating-point values are converted to character strings or bit strings, the length of the resulting string is determined by p, not by the actual value. For a discussion of conversion rules, see the chapter Data Type Conversions. Caution is necessary when using floating-point constants in arithmetic expressions. Floating-point constants are considered to be of type Float Decimal, and the rules for the precision of arithmetic results specify that the precision of the result of a floating-point operation is the maximum of the precisions of the operands. Consider the following example: SAMPLE2: PROCEDURE OPTIONS(MAIN); DECLARE X FLOAT BIN(52); X = 1E0 + .4999E0; PUT SKIP LIST(X); END SAMPLE2; The answer printed by this program is, surprisingly, .500000000000000E+000. This is because the two constants are Float Decimal with precisions of 1 and 4, respectively. The addition is performed and the result is converted to Float Decimal(4); the intermediate result of 1.4999 is rounded to 4 decimal digits, and the result is converted to Float Binary and stored in X. An attempt to correct this might be to change the expression to read X = BINARY(1E0) + BINARY(.4999E0); This does the computation in Float Binary. However, this converts the first constant to Float Bin(4) and the second to Float Bin(14), and does the computation in short floating-point on most machines. The short floating-point result is lengthened to Float Bin(52) and is then stored in X, giving an answer of 1.499900013208389E+000. The correct fix is to use the two-argument form of the BINARY built-in function: X = BINARY(1E0,52) + BINARY(.4999E0,52); This produces long floating-point constants and the computation is done with maximal precision, printing 1.499900000000000E+000. Another solution would be to rewrite the constants using trailing zeros to indicate a more precise constant: X = 1.0000000000000000E0 + .4999000000000000E0; This also gives 1.499900000000000E+000, since the computation is done in large enough precision and the result is converted directly to a high-precision floating-point value. In general, when using floating-point constants in arithmetic expressions with floating-point variables, the precision of

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (71 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

the result can be controlled by using the FLOAT and BINARY built-in functions on the operands. The results of operations on two floating-point constants may not be what is expected. Exponentiation, MOD, and all transcendental functions (including SORT) operations on floating-point decimal data are actually performed using the floating-point binary operations. Thus, the range of the operands and the results of these operations are limited to the ranges for floating-point binary numbers. Parent topic: Arithmetic Data Related information Data Type Conversions Open PL/I User's Guide

Send feedback about this topic

2.3. Picture Data


Picture data represents fixed-point decimal or character values that are stored internally as character strings. The strings contain the characters that represent the numeric or character values in a specified-format (as indicated by special embedded symbols, such as a period or a comma). Picture data is best used to manipulate a string or numeric quantity arithmetically and then print or display its value using a special output format. A pictured value is any value whose data type is either declared by a PICTURE attribute or is acquired by the P format in a FORMAT statement. Picture characters are the special characters that make up the picture specification in the PICTURE attribute and in the P format item. Following are examples of picture specifications declared by the PICTURE attribute: DECLARE DECLARE DECLARE DECLARE DECLARE F G H I J PICTURE PICTURE PICTURE PICTURE PICTURE '$ZZ,ZZZV.99CR'; '$$$,$$$V.99-'; '$**,***V.999'; '----9V.999'; '9999V9999S';

If the value -1234.56 was assigned to each of the variables in these examples, the resulting picture values would be as follows:

Repetition factors can be used for sequences of identical picture characters. For example, the following declaration of J is equivalent to the one given above: DECLARE J PICTURE '(4)9V(4)9S';

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (72 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Picture Specification Characters Rules for Using Numeric Picture Data Picture Repetition Factors

Parent topic: Data Types Send feedback about this topic

2.3.1. Picture Specification Characters


A picture specification is a sequence of picture characters. A picture specification can be either a character picture specification or a numeric character picture specification. The picture specification is enclosed in single or double quotation marks. The sequence of picture characters describe the contents of each position of either a character data item or numeric character data item, as well as the contents of the output. An A or X character in the picture specification defines it as a character picture specification. A picture specification without an A or X character is a numeric character picture specification.

Character Picture Specification


A character pictured item consists of alphabetic characters, decimal digits, blanks, currency symbols, and punctuation characters. A character picture specification includes:

Character Description

X, A, 9

Validate each character of data with allowed character set.

The character picture characters are:

Character Description

Any character of the 256 possible bit combinations represented by the 8-bit byte.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (73 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Any alphabetic or extra-lingual (#, @, $) character, or blank. Any digit, or blank. Blanks are only allowed for character data.

A character picture specification describes a nonvarying character data item. You can specify that any position in the data item contain characters only from certain subsets of the available character set. Data consists of alphabetic characters, decimal digits, and blanks. The only valid characters in a character picture specification are X, A, and 9. When a character value is assigned or transferred to a picture character data item, the particular character in each position is validated according to the corresponding picture specification character. If the character data does not match the specification at a given position, the CONVERSION condition is raised for the invalid character. In the following example, valid values for PartNum include: 'BF123M' 'KL092/' 'BT013' declare PartNum picture'AA999X'; put skip edit(PartNum)(P'AA999X');

Numeric Character Picture Specification


A numeric character pictured item consists only of decimal digits, an optional decimal point, and optional plus or minus signs. While other arithmetic characters such as currency symbols can also be specified, they are not part of the variable's numeric character value. Other arithmetic characters however are stored with the digits and are part of the variable's character value. A numeric character picture specification includes:

Category

Character

Description

decimal place character

Affects the numeric interpretation of the value only. The decimal point character is not actually stored. Mark the positions occupied by decimal digits and affect both the numeric interpretation and character representation of the value.

digit characters

9, Z, *, Y

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (74 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

encoded sign characters

T, I, R

Represent a digit that has the sign of the value encoded in the same position with the digit, thereby affecting both the numeric interpretation and character representation of the value. These characters can be used wherever the digit specifier '9' is valid. Indicates digits or symbols to be inserted in the internal representation of a character. (See the section Drifting Characters and Strings.) Inserted between digits to indicate that characters are inserted in the internal representation of the pictured value. Drifting characters also function as insertion characters when they are used singly. Always specified as two-character symbols. (See the section Credit and Debit Characters.)

drifting characters

$, +, , S

insertion characters

Decimal point (.), comma (,), slash (/), and space (B)

credit and debit

CR, DB

Note: A character picture specification cannot be mixed with numeric picture specification. However the character 9 can be used both as a character picture character and a numeric picture character. The following describes the numeric picture characters.

Character

Description

Indicates the position of the "assumed" decimal point. All digit positions to the right of the 'V' are fractional digits. Any value assigned to a pictured value is first scaled so that its decimal point is aligned with the 'V'. Only one 'V' character can appear in a picture. If a

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (75 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

picture does not contain the 'V' character, it is assumed to be at the right end of the picture, implying an integer value. B, ./ Indicate the positions at which a space (B), comma, decimal point, or slash, respectively, are inserted. These picture characters are inserted into the pictured value only if they are preceded by a nonzero digit or if they are preceded by a '9' or 'V' picture character. If they are not inserted, a zero suppression character (a blank) or an asterisk (*) is inserted instead. If an asterisk or drifting string occupies the position preceding the insertion character and that position corresponds to a leading zero, the asterisk or drifting string character also suppresses the insertion character. The 'V' and

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (76 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

decimal point (.) must be adjacent to one another to ensure that the decimal point is in the same position in both the numeric and character interpretations. The period should follow the 'V' to ensure that it will be in the correct location and will appear whenever any fractional digit is significant. Z Indicates a decimal digit with leading zero suppression. The 'Z' causes zero suppression using a blank as the suppression character. A 'Z' must not be preceded by a '9' or a drifting string. A picture containing a 'Z' must also not contain an asterisk (*). If 'Z' picture characters appear to the left of 'V', all leading zeros in positions corresponding to those 'Z' characters are suppressed. Nonzero digits and significant zeros are never

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (77 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

suppressed. Suppressed zeros are represented by spaces. If a 'Z' appears to the right of 'V', all digits in the value must be indicated by 'Z' characters. Fractional zeros are then suppressed only if all fractional digits are zero and all integer digits are suppressed. In this case, the internal representation contains only spaces in the digit positions. Note: Refer to the examples in the section Rules for Using Picture Data. * Indicates a decimal digit with leading zero suppression. The '*' causes zero suppression using an asterisk as the suppression character. An '*' must not be preceded by a '9' or a drifting string. A picture containing an '*' must also not

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (78 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

contain a 'Z'. The rules for '*' are otherwise the same as those for 'Z'. S Indicates the position of the plus sign (+) or minus sign (-), which may or may not be drifting. The 'S' causes the plus sign to be inserted if the numeric value is greater than or equal to zero, and causes the minus sign to be inserted if the value is less than zero. If an 'S' occurs more than once in a picture, the entire field of 'S's is a drifting string and can only contain a 'V' and one or more 'B' , '.' or '/' picture characters. Such a field cannot be preceded by a '9', 'Z', or '*', and if it contains a 'V' followed by one or more 'S's, it cannot be followed by a '9'. The total number of digits represented by a drifting string is one less than the number of 'S's in the field. The
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (79 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

digits are zero suppressed and a sign of '+' or '-' is inserted immediately preceding the most significant digit of the value. A single 'S' causes a sign of '+' or '-' to be inserted into the pictured value, at the location implied by the position of 'S' in the picture. + Indicates the position of the plus sign (+) to be inserted if the numeric value is greater than or equal to zero. Operates exactly like 'S', except that the sign of negative values is indicated by a blank. Indicates the position of the minus sign () to be inserted if the numeric value is less than zero. Operates exactly like 'S', except that the sign of positive values is indicated by a blank.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (80 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Indicates the position of the dollar sign ($) to be inserted. Operates like 'S', except that a '$' is inserted instead of either sign. Indicates a decimal digit, including leading zeros. The position occupied by '9' always contains a decimal digit, regardless of whether the digit is, or is not, significant in the numeric interpretation of the pictured value. Indicates the position of a decimal digit in which the zero digit is always suppressed by a blank, regardless of the position of 'Y' relative to other picture characters.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (81 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

CR

Indicates the position at which 'CR' is inserted if the number is less than zero. These two characters must appear as a pair on the rightmost end of the picture. They are replaced by two blanks in internal representation if the value is not negative. Indicates the position at which 'DB' is inserted if the number is less than zero. Like 'CR,' these two characters must appear as a pair, may only appear on the rightmost end of the picture, and are replaced by two blanks in internal representation if the value is not negative. Indicates the position of a decimal digit with an encoded plus or minus sign. The digit contains an encoded plus sign if the numeric value is greater than or equal to zero and an encoded minus sign if the value is less than zero. (See table

DB

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (82 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

below for representations of encoded sign digits.) I Indicates the position of a decimal digit with an encoded plus sign if the numeric value is greater than or equal to zero. If the value is less than zero, the position contains an ordinary digit. Indicates the position of a decimal digit with, possibly, an encoded minus sign if the numeric value is less than zero. If the value is greater than or equal to zero, the position contains an ordinary digit.
ASCII Character ASCII Character

Digit

Digit

0 1 2 3 4 5 6 7 8

} J K L M N O P Q

+0 +1 +2 +3 +4 +5 +6 +7 +8

{ A B C D E F G H

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (83 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

+9

Parent topic: Picture Data Related information Drifting Characters and Strings Credit and Debit Characters Rules for Using Picture Data

Send feedback about this topic

2.3.2. Rules for Using Numeric Picture Data


The rules for using numeric picture data are as follows: 1. A numeric picture cannot contain more than one sign character ('+', '', 'S', 'T', 'I', 'R', 'CR', or 'DB') unless all such sign characters are part of a drifting string. 2. When a zero value is assigned to a numeric pictured variable and the numeric picture does not contain at least one '9', the entire value is filled with blanks or with asterisks (*), depending on which zero-suppression character was used. 3. When a nonzero value is assigned to a numeric pictured variable, and the 'V' is followed by zero-suppression characters or by part of a drifting string, the 'V' stops zero suppression. For example: DECLARE A PICTURE 'ZZZV.ZZ'; DECLARE B PICTURE '***V.**CR'; In this example, a value of . 01 assigned to A and B produces assigned to A and B produces and ********. and . . A value of zero

4. If a 'V' is not given, a 'V' is implied at the rightmost end of the numeric picture. 5. Each '9', 'Z', or '*' is considered to be a digit of precision. Within a drifting string each 'S', '+', '', or '$', except the first one, is considered to be a digit of precision. All digits of precision following the 'V' are fractional digits. For example: DECLARE A PICTURE 'ZZZV.ZZ' DECLARE B PICTURE '---V.z--' In this example, A has a precision of (5,2), while B has a precision of (4,2). 6. Negative values cannot be assigned to a numeric pictured variable unless the picture contains a 'CR', 'DB', '', or 'S'. An error condition is signaled if a negative value is assigned to a numeric pictured variable that does not contain 'S', '+', '', 'T', 'I', 'R', 'CR', or 'DB'. 7. Values assigned to numeric pictured variables are truncated and aligned with the `V' as they would be when assigned to a fixed decimal variable of the equivalent precision.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (84 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

8. Used in contexts that expect an arithmetic value, or used with a relational operator, numeric pictured values are converted to fixed-point decimal values with a precision p and q that are determined by the numeric picture. 9. A numeric pictured value is operated upon as if it were a character-string value only when it is assigned to a character-string variable, and when it is an operand of the concatenate operator or of a built-in function that expects character-string operands. In all other contexts, numeric pictured values are operated upon as if they were fixed-point decimal values. Following are more examples of picture format output.

Example

Data

Picture

Output

1 2 3 4 5 6 7 8 9 10 11 12

12345.60 1.23 1.23 1234.56 11011111 011335 1234567890 .33 .75 1234567.89 -1234567.89 1023

$SSSSSSSSV.99 **********V.99 ZZZZZZZZZZV.99S Z.ZZZ ZZZV,99 9999B9999 **/**/** 999999999V.99 ZV.ZZ ZV.ZZ $999,999,999V.99DB $999,999,999V.99CR YYYYY

+12345.60

.********1.23 1.23 1.234,56 1101 *1/13/35 234567890.00 .33 .75 $001,234,567.89 $001,234,567.89CR 1 23 1111

In example 1, '$' is a static character because it appears only once, whereas 'S' is a drifting character because it appears all the way to the decimal. In examples 2, 3, and 4, the characters 'Z' and '*' are zero-suppression characters. The asterisk prints wherever a zero or blank would have printed, and the 'Z' substitutes blanks. In example 5 the insertion character 'B' results in a space (blank). A blank is inserted wherever the 'B' appears in the numeric picture format unless it is in a field of zero-suppression characters that are suppressing zeros at the time. In example 7, the appearance of the character '9' results in the printing of a digit. All digits 0 through 9 are printed, except the leading one, which is truncated. In examples 8 and 9, the character 'V', once encountered, turns off suppression; all characters after the 'V' are printed. Note that in Example 8, 'V' is not used before the decimal point, so the point is turned off, not on. Examples 10 and 11 show the result of positive and negative data applied to numeric pictures that contain either 'CR' or 'DB'.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (85 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Drifting Characters and Strings Credit and Debit Characters

Parent topic: Picture Data Send feedback about this topic

2.3.2.1. Drifting Characters and Strings


Used alone in a picture, one drifting character marks the position where a special symbol or space is to be inserted. It does not affect the value's numeric interpretation. In this context, the character must appear either before or after all characters that specify digit positions. If a series of n (n >1) drifting characters appears in a picture, the rightmost n-1 of the characters in the series also specify digit positions. If the digit is a leading zero, the leading zero is suppressed, and the leftmost character "drifts" to the right. In internal representation, the character appears either in the position of the last drifting character in the series or immediately to the left of the first significant digit, whichever comes first. In this context, the n-1 drifting characters also define a portion of the numeric precision of the picture variable, because they describe at least some positions occupied by decimal digits. A drifting string is a series of more than one of the same drifting character. Only one drifting string can be used in a picture; other drifting characters can be used only individually to designate insertion characters, not digits. The 'Z' and '*' characters cannot appear to the right of a drifting string. A digit position cannot be specified to the left of a drifting string. These rules apply to insertion characters embedded in a drifting string:

If the drifting string contains an insertion character, the insertion character is inserted in the internal representation only if a significant digit appears to its left. In the position of the insertion character, a space appears if the leftmost significant digit is more than one position to the right; the drifting symbol appears if the next position to the right contains the leftmost significant digit. If the drifting string contains a 'V' character, all digit positions to the right of the 'V' (the fractional digits) must also be part of the drifting string. Insignificant fractional digits are suppressed only if all integral and fractional digits are zeros; if so, they are replaced by spaces in the internal representation. If any digit is not zero, all fractional digits appear as actual digits. Insertion characters that appear to the immediate right of a drifting string are considered part of the drifting string.

Note: Refer to the examples in the section Rules for Using Numeric Picture Data.

Parent topic: Rules for Using Numeric Picture Data

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (86 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Related information Rules for Using Numeric Picture Data

Send feedback about this topic

2.3.2.2. Credit and Debit Characters


Regardless of which character pair is included, 'CR' or 'DB', that character pair appears in the internal representation if the numeric value is less than zero. If the numeric value is greater than or equal to zero, the associated positions in the internal representation contain two spaces. The credit and debit characters are always inserted with the same case used in the picture; for example, if lowercase 'db' is used in the picture, then lowercase letters are inserted into the pictured value, and if the combination of uppercase and lowercase characters, such as 'Db', is used, 'Db' is inserted into the pictured value. The 'CR' and 'DB' character pairs cannot be used in the same picture, and neither pair can be used in the same picture with any other character that specifies the sign of the value, namely, 'S', '+', '' and the encoded-sign characters ('T', 'I', 'R'). Parent topic: Rules for Using Numeric Picture Data Send feedback about this topic

2.3.3. Picture Repetition Factors


A picture repetition factor is an integer specifying the number of times the following picture character is to be repeated. The repetition factor is enclosed within parentheses (there can be no blanks within the parentheses). If the value of the repetition is 0, the following picture character is ignored. For example: pic '(4)9V(2)9' is the same as pic '9999V99'

Parent topic: Picture Data Send feedback about this topic

2.4. Character-String Data


A character-string value is a sequence of characters. The number of characters in a sequence is called the length of the sequence. In Open PL/I, the maximum length of a string value is 32767 bytes or characters. A character-string of zero length is called a null string. Note: Any string produced as an intermediate result requires storage allocated either on the stack or in the system storage area used to support the ALLOCATE statement. Allocation of a large temporary storage block that exceeds the amount of available storage results in a signal of the ERROR condition.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (87 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

A character-string variable or character-string valued function is declared with the following attributes: CHARACTER(n) or CHARACTER(n) VARYING where n is an integer valued expression that specifies the maximum length of all string values that can be held by the variable or returned by the function. The VARYING attribute causes the string variable or function to hold or return values of varying lengths. Internally, the length of the varying string is recorded along with the value. Varying strings are not padded to assume their maximum length, n. The representation of a varying string variable in storage is such that any string up to n characters may be held by the variable, and the length of the current string is retained as part of the value. Without the VARYING attribute, a string variable or function always holds or returns values of length n. An assignment to a nonvarying string always extends short values with blanks on the right to make them n characters long. Assignments of a string of more than n characters to either a VARYING or a nonvarying string variable cause only the leftmost n characters to be assigned and excess characters to be truncated. Character-string values are compared from left to right using the collating sequence of the computer. Strings of unequal length are compared by effectively extending the shorter string with blanks on the right. Nonvarying character-string variables always occupy exactly n bytes of storage. As elements of arrays or members of a structure, they begin on the next available byte and are not aligned on word or other storage address boundaries. This permits an array of nonvarying characters to be stored and accessed as if it were a single string. See the section Storage Sharing in the chapter Storage Classes. Varying character-string variables always occupy n+2 bytes of storage. The first 2 bytes contain an integer L (0 <= L <= n) that specifies the length of the string value currently stored in the variable. The string text occupies the first L bytes of the storage following the 2 length bytes. The value of the last nL bytes of the variable is undefined. The value L can be accessed using the LENGTH built-in function. An array of varying character strings cannot be accessed as if it were a single character string. See the Open PL/I User's Guide for specific alignment of varying character strings. A character-string constant is written in the following format: 'Any characters except quote' If an apostrophe is required within the constant, it must be written as an adjacent pair of apostrophes. Examples: 'ABC' 'He said, "I don"t know."' '' In these examples, the second string displays a pair of single quotation marks used within the text string "don't". This text string also shows that the double quotation mark is insignificant as a delimiter of a character-string constant. The string in the last example is a null string.

String Repetition Factors

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (88 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Parent topic: Data Types Related information Storage Sharing Open PL/I User's Guide

Send feedback about this topic

2.4.1. String Repetition Factors


Repetition factors can be used with character and bit strings. For example: (4)'Abc' is equivalent to a character constant where 'Abc' is repeated four times, 'AbcAbcAbcAbc' and (4) '10'B is equivalent to '10101010'B The maximum string repetition factor is 32767. Parent topic: Character-String Data Related information Picture Repetition Factors

Send feedback about this topic

2.5. Wide Character-String Data (UTF-16 Support)


A wide character-string value is a sequence of double-byte characters or byte-pairs. The number of byte-pairs in a wide character string or sequence is called the length of the string or sequence. In Open PL/I, the maximum length of a wide string value is 16383 byte-pairs or double-byte characters. The byte-pairs are always stored in big-endian format. A wide character-string of zero length is called a null wide string. Note: Any string produced as an intermediate result requires storage allocated either on the stack or in the system storage area used to support the ALLOCATE statement. Allocation of a large temporary storage block that exceeds the amount of available storage results in a signal of the ERROR condition. A wide character-string variable or character-string valued function is declared with the following attributes: WIDECHAR(n) or
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (89 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

WIDECHAR(n) VARYING where n is an integer valued expression that specifies the maximum length of all wide string values that can be held by the variable or returned by the function. WCHAR can be used as a synonym for WIDECHAR. The VARYING attribute causes the string variable or function to hold or return values of varying lengths. Internally, the length of the varying string is recorded along with the value. Varying strings are not padded to assume their maximum length, n. The representation of a varying string variable in storage is such that any string up to n wide characters may be held by the variable, and the length of the current string is retained as part of the value. The length field is always stored according the native architecture of the machine for fixed binary (15) data items. Without the VARYING attribute, a wide string variable or function always holds or returns values of length n. An assignment to a non-varying string always extends short values with blanks (0x0020) on the right to make them n wide characters long. Assignments of a string of more than n wide characters to either a VARYING or a non-varying string variable cause only the leftmost n wide characters to be assigned and excess characters to be truncated. Character-string values are compared from left to right using the binary values of the byte-pairs. Strings of unequal length are compared by effectively extending the shorter string with blanks (0x0020) on the right. Non-varying character-string variables always occupy exactly n*2 bytes of storage. As elements of arrays or members of a structure, they begin on the next available byte and are not aligned on word or other storage address boundaries. This permits an array of non-varying characters to be stored and accessed as if it were a single wide string. Varying wide character-string variables always occupy (n*2)+2 bytes of storage. The first 2 bytes contain an integer L (0 <= L <= n) that specifies the length of the wide string value currently stored in the variable. The string text occupies the first L*2 bytes of the storage following the 2-byte length field. The value of the last n-L byte-pairs of the variable is undefined. The value L can be accessed using the LENGTH built-in function. An array of varying wide character strings cannot be accessed as if it were a single wide character string. See the Open PL/I User's Guide for specific alignment of varying character strings.

Restrictions

All WIDECHAR byte-pairs are stored in Big Endian format. All WIDECHAR VARYING length-fields are stored in the native machine architecture for integer values. WIDECHAR characters in source files is not supported. W string constants is not supported. WIDECHAR expressions in stream I/O is not supported. Implicit conversions to/from WIDECHAR in record I/O are not supported. Implicit endian-ness flags in record I/O are not supported. Only Big Endian byte-pairs within WIDECHAR files is supported. WIDECHAR(x) VARYINGZ is not supported. Surrogate pairs are not supported.

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (90 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

UTF-8 is not supported.

Wide Character String Constants


A wide character-string constant must written as a Wide Character String Hexadecimal Literal. For example: Dcl wstr widechar (2) init (039103AAWx) ; /* Greek upper case ALPHA OMEGA */ For wide character string literals with all byte-pair binary values < 0x0080 (ASCII collating sequence 0 - 127 hex), character string literals may be used, and the compiler will do the appropriate internal conversion to type WIDECHAR. For example: Dcl wstr widechar (32) varying init (Hello Widechar!!); Parent topic: Data Types Send feedback about this topic

2.6. Bit-String Data


A bit-string is a sequence of binary digits (bits). The number of bits in the sequence is called the length of the value. A bit-string of zero length is called a null string. A bit-string variable or bit-string valued function is declared with the following attributes: BIT(n) or BIT(n) ALIGNED | UNALIGNED where n is an integer valued expression that specifies the maximum length of all string values that can be held by the variable or returned by the function. If a value of less than n bits is assigned to a bit-string variable, the variable is extended on the right with zero bits to make it n bits long. If a value of more than n bits is assigned, only the leftmost n bits are stored, and the excess bits are truncated. The ALIGNED attribute causes the associated bit-string variable to be aligned on the storage boundary (described in your Open PL/I User's Guide) so as to make it more efficiently accessed. This attribute may also cause the variable to occupy more than n bits, but it does not increase the size of values that can be stored in the variable. The UNALIGNED attribute causes the associated bit-string variable to be aligned at the next available bit so as to reduce storage requirements. If neither ALIGNED nor UNALIGNED is specified, UNALIGNED is assumed by default. In the following structure declaration, DECLARE 1 2 2 2 2 S A B C D ALIGNED, BIT(3), BIT(7) UNALIGNED, BIT(1) UNALIGNED; BIT(5);

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (91 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

the bit strings are stored as follows:

In this example the A and D strings are aligned because they inherit the ALIGNED attribute from the structure declaration. A bit string occupies a full byte. If the structure S had been declared with the UNALIGNED attribute, the A and D strings would be unaligned. Bit-string values are compared from left to right, a bit at a time until an inequality is found. The shorter operand is effectively extended by zero bits on the right to make it the length of the other operand for purposes of comparison. A bit-string is not a word of storage in a computer and is not an arithmetic value. It is a sequence of bits that is always operated upon from left to right, just as a character string is operated upon from left to right. A bit-string constant is written as a quoted string of zeros and ones followed by a B. A bit string of length one is a boolean value with the possible values of '0'B and '1'B, which denote false and true, respectively. Note: No assumptions should be made about the form in which a bit-string is stored. Examples: '1'B '10110'B 'O'B ''B The last string in the previous set of examples is a null bit string. Bit-string constants may also be written using a string of characters to represent the bit string: 'character string'Bn where n is 1, 2, 3, or 4 and is the number of bits each character represents. The table below gives the set of permissible characters and shows the corresponding bit-string values. In this table, a '' indicates 'invalid.'

Character

B or B1

B2

B3

B4

0 1 2 3 4 5 6

0 1

00 01 10 11

000 001 010 011 100 101 110

0000 0001 0010 0011 0100 0101 0110

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (92 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

7 8 9 A B C D E F
For example:

111 _

0111 1000 1001 1010 1011 1100 1101 1110 1111

BitString

Equivalent Value

'073'B3 'A04'134

'000111011'B '101000000100'B

Parent topic: Data Types Send feedback about this topic

2.7. Area Data


An area is a region of storage in which based variables can be allocated and freed. Area variables can have any storage class and may be scalars or arrays. Explicit declaration with an area attribute has the following format: AREA[(exp [REFER (variable)])] or AREA (*) The exp used with the area attribute specifies the number of bytes reserved for the area. This size is rounded up to an 8-byte boundary as necessary. For an area with the STATIC storage class, the size must be an integer constant. For areas having the AUTOMATIC, CONTROLLED, or BASED storage classes, the size is defined by an integer expression; if an area is a member of a BASED structure, however, the size specification can use the REFER option. If neither expression nor asterisk is specified, the default size is 1000 bytes. For example, DECLARE AREA1 AREA2 AREA(4096), AREA,

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (93 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

1 S BASED, 2 X FIXED BIN(15), 2 AREA3(1024 REFER(X)); An alternate way to declare an AREA is implicitly, through its use in the following contexts:

The IN option of an ALLOCATE statement. For example: ALLOCATE X IN(A1); The OFFSET attribute of an offset variable declaration. For example: DECLARE 0 OFFSET(A1);

Area variables are always aligned on 8-byte boundaries. The UNALIGNED attribute is not applicable to AREA variables. Only based variables can be allocated in an area. Use of an area allows related items to be allocated and freed only in that region of storage reserved for the area. The area can be assigned or transmitted as a unit, complete with all the allocations it contains. To preserve the desired alignment constraints in the area, the size of any allocation within the area is always rounded to an 8-byte boundary. The amount of reserved storage that is actually in use is known as the "extent" of the area. When first allocated (prior to any allocation in it), the extent of the area is zero. The maximum extent is represented by the "area size." When a based variable is allocated or freed, the extent of the area is updated to reflect the change in the amount of storage in use. In addition, when a based variable is freed, the storage it occupied is added to a chain of available storage blocks within the area. The area extent and the free chain are maintained in an 8-byte control block, adjacent to the space reserved for the area. Areas may be assigned and passed as arguments. However, areas cannot be compared or otherwise have any operators applied to them. When an area variable is assigned to another, all allocations in the target area are freed and the extent of the target area is set equal to that of the source area. The AREA condition is raised for an illegal area assignment detected at run-time. This situation occurs if the maximum size of the source area exceeds that of the target area. The AREA condition is also raised when an attempt is made to allocate a based variable within an area that has too little free storage to accommodate it. For more information about the AREA condition, see the "Area" section in the section ON in the chapter Statements. Offset variables are used to indicate the locations of based variables within the area. See the discussion in the section Offset Data. Parent topic: Data Types Related information ON Offset Data

Send feedback about this topic

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (94 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

2.8. Locator Data


Locator data is data whose purpose is to specify the location of other, usually based or controlled, data. Open PL/I supports two types of locator data: pointers and offsets.

Pointer Data Offset Data

Parent topic: Data Types Send feedback about this topic

2.8.1. Pointer Data


A pointer value is the address of a variable's storage. For example: DECLARE K FIXED BINARY(15); DECLARE A(5) FIXED BINARY(15); DECLARE P POINTER; . . . P = ADDR(A(K)); In this example, P is a pointer variable that is capable of holding the address of any variable, with the possible exception of unaligned bit strings (for more information, see your Open PL/I User's Guide). The assignment statement uses the ADDR built-in function to calculate the address of A (K) and assigns that address as the value of P. A pointer is used with a template to access the storage to which it points. For example: DECLARE X FIXED BINARY(15) BASED; . . . P->X = 10; In this example, X is a based variable (that is, a template) describing a fixed-point binary integer. P is the pointer variable from the example at the beginning of this section. The assignment assigns 10 to A (K). Pointers are often used to locate the storage of dynamically allocated based variables as described in the section Based Variables in the chapter Storage Classes, but may provide a mechanism for accessing another variable's storage, as shown in the previous two examples. The null pointer value is produced by the NULL built-in function. It is a unique value that does not address any variable and is used to indicate that a pointer variable does not currently address anything, as shown in the following example: DECLARE CHAIN_HEAD POINTER; . . .
http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (95 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

CHAIN_HEAD = NULL(); The internal representation of NULL is determined by the -setnull compiler option. For more information on compiler options, see your Open PL/I User's Guide. Pointer values may be assigned, compared for equality or inequality, passed as arguments, and returned from functions, but no calculations or conversions can be performed on them. They cannot be transmitted in stream I/O. If the variable whose storage is addressed by a pointer value is freed, the pointer value should no longer be used. Use of such a pointer to access the storage causes unpredictable results. The ADDR built-in function must not be used to calculate the address of an unaligned bit data. Consequently, when such a restriction is imposed, pointer values never address unaligned bit-string data. However, all other data can always be addressed by a pointer, regardless of the addressing capabilities of the computer. Note: The based variable that is used as a template normally must have the same data type as the variable addressed by the pointer. Violations of this rule cause unpredictable results. Programs that violate this rule and produce "correct" results may fail when compiled with optimization enabled or may fail when moved to another implementation of PL/ I. A pointer value cannot be represented by a constant. However, the NULL built-in function can be used in any context, including an INITIAL attribute, where a constant might be desired. Parent topic: Locator Data Related information Open PL/I User's Guide Based Variables Storage Sharing

Send feedback about this topic

2.8.2. Offset Data


The OFFSET attribute describes a locator data type that is used to specify the location of a based variable within an area. The format of the OFFSET attribute is: OFFSET [(area-variable)] An offset variable is a locator used only in conjunction with an area variable. The value of an offset variable specifies the location of a based variable within an area, relative to the beginning of the area. Since an offset value specifies a relative location, the value remains valid even when the area is assigned to another region of storage. To use an offset variable to identify a particular based variable, the offset variable must be associated with an area. For example: DECLARE A O X Z P AREA, OFFSET(A), FIXED BASED(O), OFFSET, POINTER;

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (96 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

ALLOCATE X IN(A) SET(O); X = 5; /* Implies area and offset */ This association can be done in the declaration by specifying the area variable, as shown in the previous example. This type of declaration has the convenience of implicitly referring to the associated area whenever a reference is made to the offset variable used as a locator. When an offset value is assigned to or compared with another offset variable, only its actual value is used the implicit area reference is ignored. However, when used as a locator, or when compared to or assigned to a pointer, the offset value is implicitly converted to a pointer by generating an address derived from the offset value combined with the address of the area with which it is associated. If this association was not done in the declaration, it can still be done using the POINTER built-in function: P = POINTER(Z, A); /* offset Z was not associated with area A in its declaration */

Note that, if the offset variable did not have an area association in its declaration, then it is only with the POINTER builtin function that the offset variable can be used as a locator to address a variable within an area. For more information, see the description of the POINTER built-in function in the section POINTER in the chapter Open PL/I Built-Ins. An OFFSET variable may be assigned a value in the following ways:

With the ALLOCATE statement For example: DECLARE X Al 01 ALLOCATE X; FIXED BIN(31 BASED(01), AREA, OFFSET(A1); /*sets 01 = to the offset of X in area A1 */

Since the locator for X and the associated area of 01 are both specified in their respective declarations, the previous ALLOCATE statement is equivalent to: ALLOCATE X IN(A1) SET(01); By assignment of another locator (offset or pointer) value By assignment of the NULL() built-in function By assignment of the OFFSET built-in function, which complements the POINTER built-in function (see the section POINTER in the chapter Open PL/I Built-Ins).

Parent topic: Locator Data Related information POINTER

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (97 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

Send feedback about this topic

2.9. Label Data


A label prefix on a statement, other than a PROCEDURE or FORMAT statement, is a declaration of a statement label. The LABEL attribute can be used to declare variables and functions whose values are labels. For example: A: PROCEDURE; DECLARE L LABEL; . . . L1: . . . L = L1; In this example, the label variable L is assigned a statement label value. A subsequent GOTO L; would transfer control to the statement labeled L1. A label value is a descriptor that consists of two parts. One part designates a statement (the instructions compiled for the statement) and the other part designates a stack frame of the block that immediately contains the statement. In the previous example, the assignment of L1 to L assigns a designator to the statement labeled L1 as part one of L, and assigns a designator to the current stack frame of procedure A as part two of L. The execution of a subsequent GOTO statement uses the stack frame designator only if the GOTO statement is executed in a block activation other than that indicated by the label value. For example: A: PROCEDURE; DECLARE L LABEL; . . . L1: . . . L = L1; . . . GOTO L; . . . B: PROCEDURE; . . . GOTO L; . . .

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (98 of 166) [16-03-2013 17:31:33]

Open PL/I Language Reference Manual

In this example, execution of the first GOTO statement simply transfers control to L1 because it occurs within the same block activation in which L1 was assigned to L (and consequently, the stack frame component of L designates the stack frame that is current when the GOTO statement is executed). However, execution of the second GOTO statement occurs within a block activation other than that whose designator was assigned to L. Execution of the second GOTO statement first uses the stack frame designator of L to terminate the block activation of B and restore the block activation of A. The second GOTO statement then transfers control to the statement labeled L1. If A were a recursive procedure with more than one activation, the statement GOTO L in B would restore the most recent activation of A. Note that a label variable that is given L as a value will denote the activation of A current at the moment L is assigned, which may not be A's most recent activation. Use of a label variable after its associated block has exited may cause unpredictable results. A single, optionally signed integer constant in the range -32768 to +32767 may be used to subscript a label. An array of labels is declared by the occurrence of subscripted labels. The elements of the array are all the subscripted labels having the same name and appearing within the same block. The highest subscript used is the upper bound of the array. The lowest subscript used is the lower bound of the array. The number of integers between the lower bound and the upper bound, inclusive, is the extent of the array. The array contains one element of each integer in the extent, although there may not be a subscripted label corresponding to the element. If you refer to an undefined element, the result is unpredictable. For example: GOTO CASE(K); CASE(1): . . . CASE(2): . . . CASE(3): . . . CASE(6): . . . In this example, CASE is a one-dimensional array of statement labels containing six elements. Elements 4 and 5 are undefined and should not be used. Using an undefined element produces unpredictable results. Label prefixes on PROCEDURE, FORMAT, BEGIN, and ENTRY statements cannot be subscripted. Because the label array is declared by label prefixes, it cannot also be declared as a LABEL variable by appearing in a DECLARE statement. Label values may be assigned, compared for equality or inequality, passed as arguments, and returned from functions, but no calculations or conversions can be performed on them. You may specify potential label values that can be assigned to a LABEL variable. They cannot be transmitted in stream I/O. Parent topic: Data Types Send feedback about this topic

http://documentation.microfocus.com/help/advance...nfocenter.enterprisedeveloper.vs/BKPFPFPREF.html (99 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

2.10. Entry Data


Entry constants and variables are used to invoke procedures through specific entry points. Entry values specify entry points and block activations of procedures.

Entry Constants Entry Variables Entry Values

Parent topic: Data Types Send feedback about this topic

2.10.1. Entry Constants


Entry constants are declared by labels or by PROCEDURE or ENTRY statements. The leftmost label on a PROCEDURE statement is a declaration of the primary entry point of a procedure. Secondary entry points are established by the ENTRY statement. Names of external procedures that are not part of the compiled module must be declared using an ENTRY attribute and, if they are functions, a RETURNS attribute. For example: DECLARE E ENTRY(FIXED BINARY(15), POINTER); DECLARE F ENTRY((5) FLOAT DECIMAL(7)) RETURNS(FLOAT DECIMAL(7)); In this example, E is declared as a procedure name that requires two arguments and that must be called as a subroutine by a CALL statement. F is declared as a procedure name that must be referenced as a function. F requires an array of five Float Decimal(7) values as its arguments and returns a Float Decimal(7) result. Procedures, other than external procedures that are not part of the compiled module, are declared by their PROCEDURE statement and cannot be declared in a DECLARE statement. Failure to declare a referenced external procedure that is part of another program module results in error messages from the Compiler. Parent topic: Entry Data Send feedback about this topic

2.10.2. Entry Variables


Entry variables are variables, including parameters, that take entry values. The ENTRY attribute together with the VARIABLE attribute can be used to declare variables whose values are entry values. The ENTRY attribute can be used in a RETURNS attribute to indicate that a function returns entry values. For example:

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (100 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

A: PROCEDURE; . . . DECLARE E ENTRY VARIABLE; . . . E = A; In this example, E is an entry variable that is capable of being assigned any entry value. The assignment causes the value of E to become a descriptor of the procedure named A. Any parameter attribute or RETURNS attribute specified as part of an ENTRY attribute has no effect on the values that can be assigned to the ENTRY variable. However, when the entry variable is called, the value that it currently holds must designate a PROCEDURE statement whose parameters and RETURNS option match those given in the declaration of the entry variable. In the previous example, a program that calls E as a function or calls E with arguments is invalid and produces unpredictable results. Parent topic: Entry Data Send feedback about this topic

2.10.3. Entry Values


Like a label value, an entry value is a descriptor containing two parts. The first part designates an entry point of a procedure, and the second part designates a stack frame of the block in which the procedure is declared. The second part of an ENTRY value that designates an external procedure is null. The second part of the entry value is relevant only when there is more than one activation of a given procedure, as is the case with recursive procedures; otherwise, an entry value can be considered simply as a designator of an entry point. Entry values can be assigned, compared for equality or inequality, passed as arguments, and returned from functions, but no calculations or conversions can be performed on them, and they cannot be transmitted in stream I/O. The following discussion explains the second part of the entry value, called the stack frame designator.

The Stack Frame Designator

Parent topic: Entry Data Send feedback about this topic

2.10.3.1. The Stack Frame Designator


If a procedure references variables local to its containing procedure, the inner procedure must be given a designator to the outer procedure's stack frame for it to be able to access the outer procedure's variables. The designator to the
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (101 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

outer procedure's stack frame is the stack frame designator. Except when the outer procedure has been activated recursively, only one stack frame for the outer procedure exists. The existing stack frame is the one that is always used when the inner procedure references variables declared in the outer procedure. If the outer procedure has been activated recursively, the entry value used to call the inner procedure determines which stack frame is to be used when the inner procedure references the outer procedure's variables. For example: A: PROCEDURE RECURSIVE; DECLARE X FIXED BINARY(15); DECLARE E ENTRY VARIABLE STATIC; IF FIRST-TIME THEN E=B; ELSE CALL F; CALL G; . . . B: PROCEDURE; . . . X=5; In this example, assume that A calls G and that G calls A, then A calls F, and F calls the entry value held by E. When E is called, an activation of B results, because B was assigned to E. When that activation of B references X, two stack frames containing an instance of X exist. Two stack frames exist because two calls of A are still active. However, because the first of these two activations of A assigned B to E, E contains a designator to the first stack frame of A. Consequently, B assigns 5 to the first instance of X. If B were called directly from A, B would always use the most recent stack frame of A when referencing X. An older stack frame is used only when an entry name is assigned to an entry variable or passed as an argument to an entry parameter. When the entry name is thus passed or assigned, the current stack frame of its containing block is assigned as the second component of the entry value produced by that assignment. If the procedure name being assigned or passed as an argument is not declared within the block that is assigning or passing it, but is declared in a containing block, the containing block's stack frame is found using the same principle as was used to find X in the previous example. Once found, a designator to that stack frame is assigned as part two of the entry value. Each stack frame for a block A has a designator to a stack frame of the block that contains A. That designator is the designator that was supplied as the second part of the entry value used to activate A. Unless the activation of A was the result of calling an entry variable or entry parameter, and unless recursion has been used, the stack frame thus designated is also the immediately preceding stack frame. Parent topic: Entry Values Send feedback about this topic

2.11. File Data


A file constant is represented by a file control block, which is an internal data structure maintained by Open PL/I. A file control block can be opened or closed and can thereby be connected to various files and devices known to the
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (102 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

operating system. For example: DECLARE F FILE; In this example, F is a file constant that designates a file control block. That file control block can be opened, closed, and used to perform I/O on files and devices known to the operating system. A file variable is represented internally as a longword containing a pointer to a file control block. When evaluated, the value of the file variable is the address of the associated file's control block. A file variable is capable of being assigned any file value; it is declared using both the FILE and VARIABLE attributes. For example: DECLARE G FILE VARIABLE; DECLARE F FILE; . . . G = F; In the previous example, G is a file variable assigned the value of the file constant F. After the assignment, operations on G are equivalent to operations on F because they both designate the file control block belonging to F. File values may be assigned, compared for equality or inequality, passed as arguments, or returned from functions; however, no calculations or conversions can be performed on them, and they cannot be transmitted by stream l/o. Parent topic: Data Types Related information File Constants

Send feedback about this topic

2.12. Arrays
An array is an ordered set of values all having the same data type. Elements of an array are referenced by their position within the array. Each array has a specified number of dimensions and each dimension has a specified lower and upper bound. The default low bound of a dimension is 1. Array elements are stored in row-major order. The successive elements of a row are stored in adjacent memory locations. In arrays with more than two dimensions, the net effect is that when the elements are accessed in their storage order, the rightmost subscript varies most rapidly. Examples: DECLARE DECLARE DECLARE DECLARE A(1:4) FIXED BINARY(15); B(0:3,0:5) FLOAT BINARY(21); C(-2:10) CHARACTER(5); D(25,4,2) POINTER;

In these examples, A is a one-dimensional array capable of holding fixed-point binary values. The lower bound is 1, the upper bound is 4, and the number of elements is 4.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (103 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

B is a two-dimensional array capable of holding floating-point binary values. Both lower bounds are zero, and the upper bounds are 3 and 5. Therefore, B has 4 rows of 6 columns each. C is a one-dimensional array capable of holding character-string values each of which has 5 characters. Its lower bound is -2 and its upper bound is 10, giving it a total of 13 elements. D is a three-dimensional array capable of holding pointer values. Because no lower bounds are given, they are assumed to be 1. The array has a total of 200 elements organized as 25 planes, each of which is 4 rows in length and 2 columns in width. The maximum number of array dimensions is 8. An array bound may be any number in the range -2^31 to 2^31 -1. Array bounds are also subject to the following restrictions:

The lower bound must be less than or equal to the upper bound. The value (upper bound lower bound) must be less than 2^31 -1. The total size of the array must be less than 2^31 bytes. For information on calculating the size of an individual array element, see your Open PL/I User's Guide.

Note: The particular implementation of PL/I or the underlying operating system may also impose restrictions on the size of an individual data item, or on the total sizes of static and/or automatic data regions. For more information, see your Open PL/I User's Guide. The bounds of AUTOMATIC, DEFINED, CONTROLLED, or BASED arrays may be specified by integer-valued expressions, as explained in the chapter Storage Classes. The bounds of STATIC arrays must be integer constants. The bounds of parameter arrays can be either integer constants or an asterisk (*). If an asterisk is given as the bound of a parameter array, it represents both the lower and upper bound and means that the actual bounds of the corresponding array argument are to be used as the bounds of the array parameter. For example: DECLARE A(0:5) FIXED BINARY; CALL P(A); . . . P: PROCEDURE(X); DECLARE X(*) FIXED BINARY; . . . During the call of P in the previous example, the bounds of X are (0:5), and any reference to X is a reference to A. The elements of an array are referenced using as many subscripts as the array has dimensions. For example: DECLARE A(-2:5,4,3) FIXED BINARY; In this example, a reference to A (-2 ,1,1) is a reference to the element in the first column of the first row in the first plane. A reference to A (3,2,1) is a reference to the element in the first column of the second row in the sixth plane. A subscript of an array must be an integer valued expression. The use of fixed-point fractions or floating-point values as subscripts results in an error message from the Compiler. However, such values can be converted to integer values by use of the TRUNC, CEIL, FLOOR, or ROUND built-in functions.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (104 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Each subscript must lie within the range specified by its corresponding lower and upper bound. Unless subscript range checking has been requested, the Compiler does not produce code to check the range of subscript values. If checking is requested, any subscript that exceeds its range results in a signal of the ERROR condition. Subscripted references to array elements can be used in any context that permits a variable reference. A cross-section of an array may be referenced by using an asterisk as a subscript. The asterisk refers to the entire range of the corresponding dimension (lower bound through upper bound). In the previous example, a reference to A (*,1,1), refers to the first-row, first-column elements in all eight planes. A reference to A ( *, *,*), refers to all 96 elements of the array. Array cross-sections may be transmitted in stream or record I/O, passed as arguments, and assigned to other arrays of the same size and shape. Parent topic: Data Types Related information Storage Classes

Send feedback about this topic

2.13. Structures
A structure is a hierarchically ordered set of values that may be of different data types. The immediate components of a structure are called members of the structure. A structure that is itself a member of another structure is called a substructure. A structure that is not a substructure is called a major structure. The hierarchical organization of a structure is specified by using level-numbers, as shown in the following example: DECLARE 2 2 2 1 S, A FIXED B FLOAT T, 3 P 3 Q

BINARY, BINARY, POINTER, CHARACTER(10);

In this example, S is a major structure, also called a level-one structure. All major structures must have a level-number of 1. The members of S are A, B, and T. T is a substructure with members P and Q. Members normally have a level-number that is 1 greater than their containing structure; however, they may be given any level-number that is greater than the level-number of their containing structure and less than the level-numbers they contain. For example: DECLARE 1 S, 20 A FIXED 20 B FLOAT 20 T, 30 P 30 Q

BINARY, BINARY, POINTER, CHARACTER(10);

The structure shown in this example is equivalent to the structure shown in the example immediately preceding it. An entire structure may be transmitted in stream or record I/O, passed as an argument, or assigned to another

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (105 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

structure of identical size and shape and having members of corresponding identical data types, but no conversions or calculations can be performed on entire structures. If a structure contains one or more members with a variable size, place all such members at the end of the structure following all the members with a fixed size. This placement improves the addressing of the fixed size members. Members of structures can be referenced in any context that permits a reference to a variable. If a member's name is not otherwise declared in the same scope (that is, in the same block or containing block), the member may be referenced by its name alone. The name of a member must be unique within its immediately containing structure, but may be used as the name of members of other structures or as the name of a nonmember. If a member's name has been used for more than one object, each reference to the member must be sufficiently qualified by the names of its containing structures to uniquely identify the intended member. In a qualified reference, the names used are listed in their hierarchical order, separated by periods. For example: DECLARE DECLARE A FIXED BINARY; 1 S, 2 A FLOAT BINARY, 2 T, 3 A POINTER;

In this example, a reference to A is a reference to the fixed-point variable. A reference to S.A is a reference to the floating-point variable. A reference to T.A or S.T.A is a reference to the pointer variable. Use of the major structure name as a qualifier is recommended. It is also advisable to avoid using the same member name more than once anywhere within the major structure or any contained structures. For more information, see the section Reference Resolution in the chapter References. A structure may have the UNION attribute applied to it, which causes all immediate members of that structure to occupy the same memory locations. For more information, see the chapter Declarations and Attributes. Parent topic: Data Types Related information Reference Resolution Declarations and Attributes

Send feedback about this topic

2.14. Arrays of Structures


Structures, like other variables, can be declared as arrays and can contain arrays as members. For example: DECLARE 2 2 2 1 S(5), A FIXED BINARY, B(4) FLOAT BINARY, T(3), 3 P POINTER, 3 Q(6) CHARACTER(10);

In this example, S is an array of 5 structures. Each structure contains a fixed- point member followed by an array of 4 floating-point values, followed by an array of 3 substructures. Each substructure contains a pointer variable followed by
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (106 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

an array of 6 character-string variables. The entire structure contains 5 occurrences of A, 20 occurrences of B, 15 occurrences of T, 15 occurrences of P, and 90 occurrences of Q. Each member of a structure array is itself an array because there exist as many instances of the member as there are elements in the structure array. If a member is an array in its own right because it has its own dimension information (as do B, T, and Q in the previous example), the array inherits the additional dimensions from its containing structures. For instance, in the previous example, Q is a three-dimensional array whose bounds are (5,3,6). Any member of a dimensioned structure is an array and must be referenced using a subscript for each of its dimensions. The subscripts may be written anywhere within the structure-qualified reference, but it is preferable to write each subscript immediately following the name to which it applies. Using the previous example to illustrate this recommended programming practice:

S(K) .A S(K) .B(J) S(K) .T(J) .Q(I)

is a reference to the Kth element of A is equivalent to B (K, J) is equivalent to S.T.Q (K, J, I) or S.T(K,J) .Q(I) or S(K,J, I) .T.Q,

It is not possible to use an asterisk to reference an entire extent (cross section) of a structure array. Members of dimensioned structures can be used only as arrays in stream I/O and as arguments to array parameters whose bounds have been specified as asterisks. They cannot be assigned, used in record I/O, used in ADDR or DEFINED, or passed to parameters with constant bounds. Subscripted references to members of dimensioned structures can be used in any context that permits a variable reference. Parent topic: Data Types Send feedback about this topic

2.15. Data Size and Alignment


Refer to your Open PL/I User's Guide for the size and alignment of each Open PL/I data type. Data not contained in a structure or array is allocated on a word or double word boundary, except for Character(1) and Bit(1) aligned data, which is allocated on a byte boundary.

ALIGNED and UNALIGNED Attributes

Parent topic: Data Types Related information Open PL/I User's Guide

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (107 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

2.15.1. ALIGNED and UNALIGNED Attributes


ALIGNED and UNALIGNED are optional data type attributes that control the storage boundary of data. ALIGNED allows the Compiler to align the data on an implementation-defined storage boundary, with the possible side effect that more bits of storage are used than specified by the declared length. (Refer to your Open PL/I User's Guide for more information.) UNALIGNED allows the Compiler to align the data on the next byte boundary (or, in the case of fixed-length bit strings, the next bit) rather than on implementation-defined storage boundaries. This can reduce storage requirements. ALIGNED or UNALIGNED can be specified for scalar, array, or structure variables. The application of either attribute to a structure is equivalent to applying the attribute to all contained elements that do not have explicit alignment declaration. Operations on ALIGNED data tend to be more efficient; operations on UNALIGNED data usually are slower. They are considered part of the data type for purposes of argument/parameter matching and storage sharing. The UNALIGNED attribute is the default for character and bit data types, while ALIGNED is the default for all other data types. The UNALIGNED attribute has no effect with an AREA variable, which is always aligned on an 8-byte boundary. Parent topic: Data Size and Alignment Related information Parameter Storage Class Storage Sharing Bit-String Data

Send feedback about this topic

3. Storage Classes

Introduction Automatic Storage Static Storage Based Variables Controlled Variables Defined Variables Parameter Storage Class Storage Sharing

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (108 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Parent topic: Open PL/I Language Reference Manual Send feedback about this topic

3.1. Introduction
Every variable has a storage class that determines how and when storage is allocated for it. A variable's storage class specifically determines whether storage will be allocated for it at compile time or dynamically during program execution. Storage classes are declared for all variables, except those used as parameters, using one of the following attributes:

AUTOMATIC STATIC BASED CONTROLLED DEFINED

If no storage class is specified for a variable declared in a procedure, other than a parameter variable, the default is AUTOMATIC. If a variable is declared outside the scope of all external procedures in a source module, the default storage class is STATIC. A parameter shares storage with its argument. As such, the storage class is ultimately determined by that of the associated argument. For convenience, a parameter may be considered to have a distinct "parameter" storage class. A variable's storage size is determined by its extents. A string variable's extent is its declared length. An array variable's extents are determined from the number of its dimensions and the range of its subscript bounds. The extents of both types of variables are evaluated when storage is allocated for the variable. The permitted forms for extents differ for each storage class and are described during the discussions of each storage class. Parent topic: Storage Classes Send feedback about this topic

3.2. Automatic Storage


Storage for an automatic variable is allocated with each activation of the procedure or the BEGIN block in which the variable is declared. Storage is allocated within the stack frame that represents that block activation. If a block is activated recursively, each of its stack frames contains a distinct instance of all automatic variables declared in that block. When a block activation ends, its stack frame is popped from the stack, thereby freeing the storage of all automatic variables allocated within it. This phenomenon normally occurs when a procedure returns to its caller or when a BEGIN block executes its END statement; however, it also occurs when a GOTO statement transfers control back to a previous block activation. In the latter case, all block activations between the one to which control is transferred and the one in which the GOTO was executed are ended. Their stack frames are popped from the stack, releasing the storage for all of their automatic variables. The INITIAL attribute can be specified in the declaration of an automatic
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (109 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

variable to initialize the variable. Extents of automatic character string and array variables may be specified as integer valued expressions, provided these do not contain references to other non-static variables declared in the same block. Extent expressions for these automatic variables are evaluated each time the containing block is activated. The extent expression values are saved in the stack frame and effectively fix the size of the automatic variable for that block activation. Subsequent assignment to a variable used as an extent does not affect the size of the associated automatic variable. For example: DECLARE STRING_SIZE FIXED; . . . COPY: BEGIN; DECLARE TEXT CHARACTER(STRING_SIZE); When the BEGIN block in this example is activated, the extent of TEXT is evaluated. The variable is allocated storage depending on the value of STRING_SIZE, which must be a valid integer value. For example: DECLARE A(N) FIXED; . . . N = 10; /* WILL NOT AFFECT THE SIZE OF ARRAY A */ In this example, the size of A is determined upon entry to the containing block by evaluating N and storing its value in the stack frame. The assignment to N does not change the size of A. Upon entry to the block, N must have a correct value and must not be a non-static variable declared in this block. Use of the HBOUND built-in function within this block activation would return the original value of N that was saved in the stack frame. Parent topic: Storage Classes Related information INITIAL HBOUND Function

Send feedback about this topic

3.3. Static Storage


Storage for a static variable is allocated by the Compiler and/or linker prior to program execution. Storage remains allocated throughout program execution. Only one instance of a static variable's storage is allocated, regardless of whether the variable is declared in a recursive procedure. Values assigned to a static variable are retained between calls to the procedure in which the variable is declared. All extents specified for static character string, 8-bit area variables, and array variables must be constants. Static variables can be declared with the INTERNAL or EXTERNAL attribute. If neither attribute is specified, INTERNAL is assumed. An internal static variable is known in its containing block and in all contained blocks, except those blocks in which the same name is redeclared. This is the normal scope rule that applies to all other variables.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (110 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

An external static variable is known in its containing block and in all contained blocks, except those blocks in which the same name is redeclared. However, all declarations of the same name that have the EXTERNAL attribute, including those in separate modules of the program, share the same storage and must specify identical attributes, including any initial values. External static variables are known and shared by all program modules in a manner similar to the common variables of FORTRAN, except that each external static variable is shared independently of others. Parent topic: Storage Classes Related information INTERNAL EXTERNAL

Send feedback about this topic

3.4. Based Variables


The BASED attribute defines a template for storage that will be accessed through the use of a locator. A based variable differs from all other variables in the sense that it is a description of storage, but does not have storage of its own. Since it has no storage, it has no address. For example: DECLARE X CHARACTER(30) BASED; DECLARE P POINTER; . . . P->X = 'ABC'; In this example, assume that an address or pointer value has been assigned to P. The reference P>X is called a pointer qualified reference, and it enables assignment to the storage addressed by P as if that storage contained a character-string variable like X. A pointer value can be obtained in two primary ways: from the address of a variable's storage as calculated and returned by the ADDR built-in function, or from the address of storage obtained dynamically by the ALLOCATE statement. For example: DECLARE K FIXED BINARY(15); DECLARE X(5) FLOAT BINARY; DECLARE Y FLOAT BINARY BASED; DECLARE P POINTER; . . . P = ADDR(X(K)); P->Y = 10; In this example, P is assigned the address of X (K) , which is returned by the ADDR built-in function. The second assignment places the value 10 in the storage location given by P in a manner prescribed by the template Y, effectively assigning 10 to X (K) . A third way to obtain a pointer value is with the POINTER built-in function, which may be used to convert an area offset value to a pointer.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (111 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The indiscriminate use of pointers to access the storage of other variables should be discouraged because of the possibilities of unexpected assignment side effects and because the excessive use of pointers makes a program hard to read. Please also note that no checking is performed to ensure that the based variable provides a data description compatible with the declaration of the reference storage. For instance, the statement P>Y = 10 might produce undesirable results if Y were declared as a data type incompatible with the data type of elements in X. For a discussion of storage sharing using based variables, see the section Storage Sharing. The ALLOCATE statement uses a based variable to allocate a block of storage that can later be accessed by a based variable together with the locator returned by the ALLOCATE statement. For example: DECLARE P POINTER; DECLARE X(C,N) CHAR BASED(P); N = 10; C = 10; ALLOCATE X SET(P); . . . P -> X(10,5) = 'A'; In the preceding example, the ALLOCATE statement allocates a storage block of sufficient size to hold a twodimensional array of 100 one-byte character values and assigns a pointer to that block of storage to P . P>X thereafter is a reference to that block of storage as an array of 100 one-byte character values. Based variables can be subscripted just like any other variable. Referring again to the previous example, the statement P> X (10,5) = ' A' assigns the character 'A' to the element in row 10 and column 5 of the array qualified by P. Since the pointer variable may also be an array, it too can be subscripted. For example: DECLARE P(3) POINTER; DECLARE X(10) FLOAT BASED; . . . ALLOCATE X SET(P(K)); In the preceding example, P (K)>X refers to the entire array of ten floating-point elements qualified by the Kth pointer element of P. Likewise, P (K) >X (J) refers to the Jth element of the floating-point array qualified by the Kth element of pointer array P. The ALLOCATE statement is the only context in which a based variable can be used without an explicit or implicit locator qualifier. In this context, the based variable is used to describe how much storage is to be allocated. Implicit locator qualification is a shorthand notation that can be used in cases where many of the references to a based variable use the same pointer. For example: DECLARE X(10) FLOAT BASED(P); DECLARE P POINTER; . . . ALLOCATE X SET(P); Because X was declared to be based on P in the previous example, unqualified references to X such as X (K) , X (5), or X are implicitly qualified by P and are equivalent to P>X (K) , P>X (5) , and P>X. Any explicit qualification, such as Q>X, may be used to temporarily override the implicit qualification and is unaffected by the specification of P in
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (112 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

BASED (P) . The extents of a based variable may be specified as integer valued expressions. The extents are evaluated for each allocation of the variable and for each reference of the variable. The extents are not captured when storage is allocated by an ALLOCATE statement. The extent expression can reference variables declared in the same block, as long as those variables have a value before the based variable is referenced. Changing the value of a variable referenced by an extent expression changes the extent of the based variable. For example: DECLARE X(N) CHARACTER(1) BASED; N = 10; ALLOCATE X SET(P); . . . N = M; P->X(5) = 'A'; In this example, the ALLOCATE statement allocates an array of ten elements. The value of M must be greater than or equal to five and less than or equal to ten; otherwise, the reference to P>x (5) is invalid and may cause unpredictable results. A block of storage previously allocated by an ALLOCATE statement can be freed by a FREE statement. For example: FREE P->X; Once freed, the storage can no longer be accessed, and any attempt to use a pointer such as P that points to the block produces unpredictable results. Note: The storage obtained by an ALLOCATE statement is freed only by an explicit FREE. If a program continually allocates memory without freeing it, the program may run out of space at run-time. Used with the ALLOCATE statement, based variables are powerful tools for applications in which the size of arrays or strings is not known at block entry and must be determined at run-time. Based variable allocations also supply a means for the dynamic creation of graph structure nodes (which may be linked by pointers to produce list and tree structures). See the example of a based structure in the section Block Activation and Recursion. It is desirable to restrict the extent of based variables to constant values whenever possible to avoid unexpected side effects and to improve program readability. If the extent must be variable, it is preferable to avoid the use of extent expressions when declaring based variables for the same reasons. The size of the based variable is evaluated for each reference to the variable. Parent topic: Storage Classes Related information POINTER Function Storage Sharing Block Activation and Recursion

Send feedback about this topic


http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (113 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

3.5. Controlled Variables


The CONTROLLED attribute specifies a variable whose storage is dynamically allocated and freed in generations, independent of block boundaries. Controlled variables are allocated only when specified in an ALLOCATE statement. After being allocated, a controlled variable remains allocated until a FREE statement names the variable. A reference to a controlled variable refers to the generation of the variable created by the most recent ALLOCATE statement. The FREE statement frees the most recent generation of the controlled variable, exposing the previous generation. For example: DECLARE STACK (STACK_ITEM_SIZE) CHAR(32) CTL; DECLARE STACK_ITEM_SIZE FIXED BIN; DECLARE I FIXED BIN; /* Push a first stack item. */ STACK_ITEM_SIZE = 4; ALLOCATE STACK; DO I = 1 TO STACK_ITEM_SIZE; STACK(I) = CHAR(I) || '_1'; END; /* Push a second stack item. */ STACK_ITEM_SIZE = 3; ALLOCATE STACK; DO I = 1 TO STACK_ITEM_SIZE; STACK(I) = CHAR(I) || '_2'; END; PUT SKIP LIST ('Print second item on the stack'); PUT SKIP LIST (STACK); /* Pop the last element on the stack. */ FREE STACK;

PUT SKIP LIST ('Print first item on the stack'); PUT SKIP LIST (STACK); /* Pop the last element on the stack. The stack is empty now. */ FREE STACK; CONTROLLED variables can be declared with asterisk (*) extents, and when such a variable is allocated, its extents can be made explicit by the use of the ALLOCATE statement with specified attributes. CONTROLLED variables can also be declared with explicit extents (constant or variable), and these explicit extents can be overridden by use of the ALLOCATE statement with specified attributes. It is also possible to specify attributes with asterisk extents in the ALLOCATE statement. This causes the extents to be copied from the corresponding extents used for the previous allocation of the same CONTROLLED variable. If an asterisk is specified in the ALLOCATE statement for one dimension of a variable, it must be specified for all dimensions of that variable.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (114 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

If level numbers are specified, the first variable in the ALLOCATE statement must be specified with a level-num of 1 and be declared as a level-1 structure, and in this case, all members of the structure must be included in the ALLOCATE statement just as they appear in the declaration of the structure. Any bound, length, size, or initial value specified in the ALLOCATE statement overrides the corresponding attribute specified in the declaration of the variable. A bound, length, or size can be specified in the ALLOCATE statement with an asterisk, and, in this case, the bound, length, or size is taken from the current generation of that CONTROLLED variable. If a bound, length, size, or initial value specified in the ALLOCATE statement contains a reference to the variable being allocated, the reference is to the current generation of the variable. Evaluations of expressions for bounds, lengths, sizes, and initial values during the execution of the ALLOCATE statement are done according to the normal rules for PL/I references, and must be capable of logical execution (that is, without circularity). Evaluations depending on the existence of a prior generation of a variable require that that generation has previously been allocated. Controlled variables provide an easy way to implement a stack, because only the most recent generation is available to the program. The ALLOCATE statement is equivalent to a push operation and the FREE statement is equivalent to a pop operation. The ALLOCATION built-in function is used to determine the number of generations of a controlled variable that are available. Examples DECLARE 1 A CONTROLLED, 2 B CHAR(*), 2 C CHAR(20), 2 D(2) FIXED BIN(31), 2 E(4,4) CHAR(*), 2 F FIXED BIN(31); ... ALLOCATE 1 A, 2 B CHAR(12), 2 C, 2 D(6), 2 E CHAR(3), 2 F INIT(128); ... ALLOCATE 1 A, 2 B CHAR(12), 2 C CHAR(10), 2 D(D(1)), 2 E CHAR(3), 2 F; In this example, the structure A is first allocated with member B of length 12, with array member D with dimension (6) instead of the declared (2), array member E with its declared dimensions of (4,4) and element lengths of 3, and member F with an initial value of 128. The second generation of A is allocated with member C of length only 10 and with the dimension of array member D the value contained in the first generation of A.D(1). DECLARE X(*,*) CONTROLLED; ALLOCATE X(3,7); ALLOCATE X(*,*); In the second allocation of array X, the bounds are implicitly (3,7), as derived from the previous allocation. For CONTROLLED parameters, CONTROLLED must be explicitly stated in the parameter descriptor for the ENTRY declaration. This is required by the PL/I language specification. For example, if you compile and link together the following two procedures: t.pl1 TSTENTM: PROC OPTIONS(MAIN); DCL DCL N CHAR(10) CONTROLLED;

TSTENT ENTRY(CHAR(10));

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (115 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

ALLOCATE N; N = 'CONTROLLED'; CALL TSTENT(N); END;

t1.pl1 TSTENT: PROC(N); DCL N CHAR(10) CONTROLLED; PUT SKIP LIST ('N = ',N); RETURN; END; Upon execution you will get: *** Condition ERROR raised *** Unhandled condition SIGSEGV at PC=004011AE N = To avoid this, add the controlled attribute to the ENTRY declaration: DCL TSTENT ENTRY(CHAR(10)CTL);

Parent topic: Storage Classes Send feedback about this topic

3.6. Defined Variables


A defined variable is one for which no storage is allocated. Instead, the variable shares the storage of a specified basis variable. A defined variable is declared with the DEFINED attribute, which also specifies the basis variable. Any reference to the defined variable is a reference to all or part of the storage of the basis variable. When the declaration of a variable includes the DEFINED attribute, that variable's description applies to the storage associated with the basis variable. For example: DECLARE A(5) CHARACTER(1); DECLARE X CHARACTER(5) DEFINED(A); In this example, X is a defined character-string variable of length 5. X shares storage with, and is an alternate description of, the array A. Similarly, the following statement: X = 'abcde'; assigns 'a' to A (1) , 'b' to A(2), and so on. The extents of a defined variable can be integer valued expressions. They are evaluated upon block entry and stored in the stack frame just like the extents of automatic variables. Such an extent expression must not contain a reference to any non-static variable declared in the same block.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (116 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

For additional information on defined variables, see the section Storage Sharing, which discusses the rules for giving alternate descriptions of storage. Parent topic: Storage Classes Related information Storage Sharing

Send feedback about this topic

3.7. Parameter Storage Class


A parameter shares storage with its argument. As such, the storage class is ultimately determined by that of the associated argument. Technically, the parameter variable itself is an AUTOMATIC variable containing the address of the corresponding argument. For convenience, a parameter may be considered to have a distinct "parameter" storage class. For example: DECLARE X FLOAT; CALL P (X); . . . P: PROCEDURE (Y); DECLARE Y FLOAT; In this example, X is an argument and Y is a parameter variable. A parameter variable is declared within a procedure declaration and receives a value when that procedure is invoked. Simple Open PL/I variable arguments are passed by reference. A parameter has a data type, perhaps a data type with extents, and in the simplest case, an argument passed to the parameter will have the same data type and extents as the parameter. If this is not the case, Open PL/I will, whenever possible, convert the argument to a value with the same data type and extents as the parameter and pass that value to the parameter. In the absence of specifications to the contrary, when a variable is passed as an argument to a parameter with matching data type and extents, the argument is passed "by reference." This means that it is the address of the actual variable itself that is passed as the argument, and the parameter is sharing storage with this variable. Hence, any assignment to the parameter is actually changing the argument variable itself. In other cases that is, when the argument is a variable whose data type and extents do not match the parameter, or when the argument is an expression, a constant, a function reference, or a simple variable enclosed in parentheses the argument is passed "by value." This means that the value of the 'argument is converted as described above and stored in a temporary location. It is the address of this temporary location that is passed as the argument. Hence, any assignment to the parameter can have no effect on any variable in the calling procedure. The precision of arithmetic data is part of its data type. This means that a Float Decimal(7) variable cannot be passed by reference to anything except a Float Decimal(7) parameter. The VARYING and ALIGNED attributes, as well as the declared string length, are part of a string variable's data type and must match those of the corresponding parameter for the parameter to share storage with the actual argument (true pass-by-reference). A picture variable can be passed by reference only if the corresponding parameter has an identical picture. The ALIGNED and UNALIGNED attributes of non-string arguments and parameters must match.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (117 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The VALUE attribute is an argument-passing attribute that indicates that the value and not the address of the parameter has been passed to the procedure. An array parameter with constant extents can be passed only those array arguments that have identical constant extents and an identical data type. A parameter structure can be passed only a structure or substructure of identical size, shape, and component data types. Array or structure arguments cannot be passed by value. The ANY attribute is an argument-passing attribute that specifies, for a parameter, that the corresponding argument can be of any data type. A procedure that has a character or bit-string parameter with a constant length may be called with string arguments of variable length or differing constant length. Since all such arguments are passed by value, they are effectively converted to the length of the parameter. For example: CALL P(A,(B)); In this example, A is passed by reference if it matches its corresponding parameter and is passed by value if it does not. B is always passed by value. If the argument is an expression, function reference, built-in function reference, constant, parenthetical variable reference, or a reference to a variable whose data type does not match that of the parameter, the argument is copied to a temporary block of storage in the caller's stack frame and is said to be passed by value. The value of the variable in the caller will not be modified if it is passed by value. Actually, the address of the temporary is passed, and the parameter shares the storage allocated to the temporary. The extents of a parameter can be either integer constants or asterisks (*). If the parameter's extents are integer constants, any argument to be passed by reference must have identical constant extents. If the parameter's extents are asterisks, its corresponding argument may have extents of any value. In the latter case, the extents of the parameter are those of its corresponding argument. For example: DECLARE A(10) FLOAT; DECLARE B(25) FLOAT; . . . CALL P(A); . . . CALL P(B); . . . P: PROCEDURE(X); DECLARE X(*) FLOAT; During the first call in this example, the extents of X are (1:10). During the second call, they are (1:25). Parent topic: Storage Classes Related information Value ANY

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (118 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

3.8. Storage Sharing


Open PL/I provides two storage classes that are explicitly designed to permit storage locations to be shared by several variables. These storage classes are BASED and DEFINED. (Use of the UNION attribute also allows variables to explicitly share storage.) Based variables are allocated no storage when they are declared. Instead, they serve to determine storage to be allocated by an ALLOCATE statement or to describe storage qualified by a pointer reference. Defined variables use the storage of a specified basis variable. A defined variable is declared with the DEFINED attribute, which also specifies the basis variable. A defined variable and its basis reference must satisfy one of the following criteria in order to share storage: 1. All variables sharing storage have identical data types. 2. All variables sharing storage are nonvarying character strings and therefore are suitable for character-string overlay defining. 3. All variables sharing storage are unaligned bit strings and therefore are suitable for bit-string overlay defining. A variable is suitable for overlay defining if it consists entirely of characters or bits that are packed into adjacent storage without gaps. (Gaps can be caused by the alignment of data in user-defined structures.)Variables suited for overlay defining are arrays, structures containing only the required type of string data, or scalar string variables. For example: DECLARE X(4,4) CHARACTER(1); DECLARE Y(16) CHARACTER(1) DEFINED(X); DECLARE Z CHARACTER(5) DEFINED(X); DECLARE 1 S BASED, 2 A CHARACTER(8), 2 B CHARACTER(8); In this example, X has a block of storage containing 16 characters. The entire block is shared by Y, but Z shares only the first 5 characters of the block. S could be used to access all 16 characters, while S.A could be used to access the first 8, and S.B could be used to access the last 8. A based character string of more than 16 characters would produce undefined results, but a string of 16 or fewer characters could be used. A similar example could be constructed using all unaligned bit data. Storage sharing of other data types requires that the data types match exactly, but an element of an array can be shared with a nonarray variable of the same data type. Similarly, a member of a structure can be shared with a nonmember of the same data type. Members of structures that have the attribute UNION also share physical storage locations with one another. A UNION is a variation of a structure in which all immediate members occupy the same physical storage location. Unions provide capabilities similar to those of defined variables. 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 designated structure occupy the same storage. An immediate member is any member having a level number greater than its containing structure but not greater than the level number of its fellow members. Typically, an immediate member has a level number that is one greater than its containing structure. (For more information on this attribute, see the section Union.) Arrays can share storage with other arrays only if they have the same data type and/or are equivalent left-to-right.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (119 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Structures can share storage with other structures only if they are equivalent, left-to-right, to the structure whose storage is being shared. Left-to-right equivalence means that the sharing structures must be valid descriptions of the left part of the storage being shared. To be a valid description of the left part of storage, the sharing structures must have identical members up to and including all members contained anywhere within the last level-two item being shared. If any part of a leveltwo item is to be shared, all of it must be shared. For example: DECLARE 1 2 2 3 3 2 S, A, B, C, D; E; DECLARE 1 2 2 3 3 T BASED, A, B, C, D; DECLARE 1 2 2 3 U BASED, A, B, C;

In this example, a reference to T.B.C is a valid reference to S.B.C, but a reference to U.B.C is not valid, because the declaration of U does not describe the entire level-two item S.B. A picture variable can share storage only with other picture variables that have identical pictures. As is the case for argument/parameter matching, the ALIGNED, UNALIGNED, and VARYING attributes and the declared length of a string variable are part of its data type and must match, unless the strings qualify for string overlay sharing. The base, scale, and precision of arithmetic variables must always match if they are to share storage. Parent topic: Storage Classes Related information Union

Send feedback about this topic

4. Declarations and Attributes

Introduction Label Prefixes DECLARE Statements Attributes of DECLARE Statements

Parent topic: Open PL/I Language Reference Manual Send feedback about this topic

4.1. Introduction
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (120 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

All variables in an Open PL/I program (except those under the control of the DEFAULT statement) must be declared. Each name, except the name of a built-in function, must be declared using a DECLARE statement (or if it is a label, by using the label as a statement prefix). Each declaration is associated with a scope or region of the program in which a reference to the associated name is valid. The scope of a declaration includes the block in which it is declared and all nested blocks, except those in which the name has been redeclared. Identifier attributes used in DECLARE statements are specified by either keyword or syntax. A name declared with the EXTERNAL attribute has the same scope rule as any other name, except that the object identified by that name is unique throughout the entire program. All declarations of a given name that have the EXTERNAL attribute identify the same object. Only files, static variables, and names of external procedures can have the EXTERNAL attribute. Files and procedures acquire the attribute by default, but static variables have internal scope unless they are explicitly declared with the EXTERNAL attribute. A given name cannot be declared more than once within the same block, unless it is declared as the name of a structure member. In that case, the name may be redeclared within the same block, provided no two members at the same level of the same structure have the same name. (See the section Scope.) Parent topic: Declarations and Attributes Related information Scope

Send feedback about this topic

4.2. Label Prefixes


A label prefix declares a name as a procedure name, format name, or statement label, depending on the type of statement to which the prefix is attached. A label prefix on a PROCEDURE statement declares a name as a procedure name. The name is declared in the block that contains the PROCEDURE statement, and its scope is that containing block and all blocks contained by the procedure. The declaration lists each parameter referenced by the PROCEDURE statement, as well as the data type specified by any RETURNS option in the PROCEDURE statement. For example: E: PROCEDURE(A,B) RETURNS(POINTER); DECLARE A FIXED BINARY; DECLARE B FLOAT DECIMAL; In this example, E is declared as a procedure name in the block that contains the PROCEDURE statement. The attributes of that declaration are RETURNS(pointer) and ENTRY(fixed binary, float decimal). The label prefix on a FORMAT statement declares a name as a format name. The name is declared in the block that contains the FORMAT statement and all contained blocks. A format name is not a statement label and cannot be used in a GOTO statement. A format name can be used only in a format statement. The label prefix of a PROCEDURE or FORMAT statement cannot be sub- scripted. A label prefix attached to statements other than PROCEDURE or FORMAT statements declares a name as a statement label. The declaration is established in the block that contains the statement to which the prefix is attached. For example, a label prefix attached to a BEGIN statement is declared in the block that contains the BEGIN statement and its scope is that containing block and all blocks contained by the BEGIN statement.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (121 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The label prefix of a PROCEDURE or FORMAT statement cannot be sub- scripted; however, label prefixes attached to statements other than PROCEDURE or FORMAT may be subscripted by a single optionally signed integer constant. Within its scope, all occurrences of a given name used in this manner must be subscripted, and all such prefixes collectively constitute a declaration of the name as an array of statement labels. For example: GOTO CASE(K); CASE(1): . . . CASE(2): . . . CASE(3): . . . CASE(6): . . . In this example, CASE is declared as an array of statement labels whose bounds are (1:6) and whose fourth and fifth elements are undefined. Defining arrays with undefined elements is not recommended, as it produces unpredictable results. An array of statement labels cannot be used as an array value, but its elements can be used in any context that permits a statement label. Procedure names, format names, and statement labels cannot be declared in a DECLARE statement in the same block, except that the names may be used as the structure member names. Names of external procedures that are part of another program module must be declared by a DECLARE statement if they are to be referenced by the current program module. (For more information, see the section Modules.) Only external procedure names can be declared by a DECLARE statement. Parent topic: Declarations and Attributes Related information FORMAT Modules

Send feedback about this topic

4.3. DECLARE Statements


A DECLARE statement declares one or more names by giving the attributes or properties of the named objects. A DECLARE statement is not an executable statement. It may appear as a part of a WHEN or OTHERWISE clause in a SELECT statement; anywhere within a procedure or BEGIN block, except as the THEN clause or ELSE clause of an IF statement; or as an ON-unit of an ON statement. For the sake of readability, all DECLARE statements belonging to a given block should be placed at the beginning of
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (122 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

that block, rather than among the executable statements.

Recommended Forms The General Form Defaults Attribute Consistency

Parent topic: Declarations and Attributes Send feedback about this topic

4.3.1. Recommended Forms


This section describes the recommended forms of the DECLARE statement within the following statement categories: simple declarations, factored declarations, and structure declarations.

Simple Declarations Factored Declarations Structure Declarations

Parent topic: DECLARE Statements Send feedback about this topic

4.3.1.1. Simple Declarations


A simple declaration defines a single name and describes its attributes. Its recommended form is: DECLARE name a1 a2 an; where name is the declared name and a1 through an are attributes. For example: DECLARE A FIXED BINARY(15); DECLARE B CHARACTER(10) VARYING STATIC INITIAL('ABC'); DECLARE C DIMENSION(5) FLOAT DECIMAL(7); The last statement in this example could also be given without the keyword DIMENSION by using the following format: DECLARE C(5) FLOAT DECIMAL(7);

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (123 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Parent topic: Recommended Forms Send feedback about this topic

4.3.1.2. Factored Declarations


Factored declarations define two or more names having the same attributes. The recommended form of a factored declaration is: DECLARE (name-1[,name-2])a1 a2an; where each name is declared to have all of the attributes a1 through an. In factored declarations, the names must be enclosed in parentheses. Examples: DECLARE (A,B,C) FIXED BINARY(15); DECLARE (P,Q) POINTER STATIC INITIAL(NULL); DECLARE (X,Y)(5) FLOAT DECIMAL(7); The last example is equivalent to the following statement: DECLARE (X,Y) DIMENSION(5) FLOAT DECIMAL(7); The bounds must be the first attribute in an attribute list if they appear without the DIMENSION keyword. Parent topic: Recommended Forms Send feedback about this topic

4.3.1.3. Structure Declarations


The declaration of a structure defines the organization of the structure and the names of members at each level of the structure. The general form of this declaration is: DECLARE 1 structure_name a1 a2 an, k member_name-1 a1 a2 an, k member_name-2 a1 a2 . an, . . . k member_namem a1 a2 an; where each member_name specifies a member of the structure preceded by a level-number, k, and where the levelnumber of each member must be greater than the level-number of its containing structure, equal to level-numbers of members at the same level, and less than the level-numbers of members it contains. The major structure name is declared as structure level 1. The only attributes given to the structure itself are storage class, ALIGNED, UNALIGNED, DIMENSION, REFER, and UNION. Each member is declared to have all attributes following its name up to the next comma or up to the end of the
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (124 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

statement. For example: DECLARE 1 S 2 2 2 STATIC, A(5) FLOAT DECIMAL(7), B FIXED BINARY(15), C, 3 D POINTER, 3 E CHARACTER(10) INITIAL('ABC');

In this example, S is a static structure with members A, B, and C. C is a substructure with members D and E. Initial attributes can be given to elementary members of static structures, but not to structures themselves. Parent topic: Recommended Forms Send feedback about this topic

4.3.2. The General Form


Following is the general form of the DECLARE statement: DECLAREd1[,d2 ]; or DCL d1 [,d2 ]; where each d is: [k]name a1 a2 an or [k](d1[,d2])a1 a2 an where k is an optional level number, each a is an attribute, and name is a name to be declared. Examples: DECLARE ((A FIXED, B FLOAT) DECIMAL, C BIT) STATIC; DECLARE 1 S STATIC, 2 (A FIXED, B FLOAT) INITIAL(0); These examples illustrate more factored declarations, as indicated by the fact that the DECLARE statements contain parenthetical lists of names. Factored declarations can be transformed into nonfactored declarations by copying the level number and attribute list of the innermost set of parentheses onto each name contained within the parentheses, removing the parentheses, and repeating this process with the next set of parentheses. After defactoring, the previous examples are: DECLARE A FIXED DECIMAL STATIC; DECLARE B FLOAT DECIMAL STATIC; DECLARE C BIT STATIC;

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (125 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

DECLARE 1 S STATIC, 2 A FIXED INITIAL(0), 2 B FLOAT INITIAL(0); Factored declarations, other than as shown in the recommended form (see the section Factored Declarations) are generally more difficult to read than their unfactored equivalents. If defactoring produces more than one level number for a given name, even if the level numbers are equal, the factored declaration is invalid and causes the Compiler to issue an error message. Specification of duplicate attributes containing more than a simple keyword is also invalid, even when the attributes are exact duplicates. Parent topic: DECLARE Statements Related information Factored Declarations

Send feedback about this topic

4.3.3. Defaults
If the attributes specified for a name in a DECLARE statement are incomplete, the missing attributes can be supplied either by the Compiler or by the user with the DEFAULT statement.

Compiler-supplied Defaults The Default Statement

Parent topic: DECLARE Statements Send feedback about this topic

4.3.3.1. Compiler-supplied Defaults


The Compiler supplies the required additional attributes, as follows:

Specified

Missing

Supplied

binary decimal fixed float static

fixed | float fixed | float binary | decimal binary | decimal internal | external

fixed fixed decimal decimal internal

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (126 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

bit character area

length length size

length of one length of one size of 1000

Defaults are also supplied for the following conditions.

STATIC is supplied if EXTERNAL is specified without a storage class and the declared name is not an entry or file constant. AUTOMATIC is supplied if the name is the name of a nonparameter variable that is not a member of a structure and no storage class was specified. The default precision is supplied if precision is not specified for arithmetic data. For information on the Open PL/I default precisions, see your Open PL/I User's Guide. VARIABLE is supplied if a storage class, array bounds, or member's level number is specified with FILE or ENTRY. EXTERNAL is supplied if FILE or ENTRY is specified and VARIABLE is neither specified nor supplied under the previous rule. In this case, the named object is a constant rather than a variable. UNALIGNED is supplied for bit-string data; ALIGNED for all other types of data.

Parent topic: Defaults Related information Open PL/I User's Guide

Send feedback about this topic

4.3.3.2. The Default Statement


You can change Compiler-supplied defaults, or you can apply a completely new set of default attributes, using the DEFAULT statement. Parent topic: Defaults Related information DEFAULT

Send feedback about this topic

4.3.4. Attribute Consistency


After default attributes have been supplied, each declaration is checked by the Compiler for consistency and completeness.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (127 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

If no data type is specified, either explicitly or by the DEFAULT statement, the declaration is invalid and incomplete. The Compiler issues an error message and supplies a type of Fixed Binary(15) for names beginning with any of the letters I through N, and Float Decimal(6) for names beginning with any other alphabetic character. A declaration is inconsistent and invalid if it specifies more than one data type or more than one storage class. These are the valid data types:

Fixed Binary(p) Fixed Decimal(p[,q]) Float Binary(p) Float Decimal(p) Picture Character(n) [Varying] Bit(n)[Aligned] Pointer Offset Area Label Entry [returns][variable] File [variable] Builtin Structure

These are the valid storage classes:

automatic based or based(pointer-reference) static internal defined(reference) parameter member of structure

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (128 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

A declaration is also inconsistent and invalid if it violates the following attribute-specific restrictions:

A name declared with the BUILTIN attribute cannot have any other attribute. A name declared with the FILE or ENTRY attribute, but without the VARIABLE attribute, is a named constant, not a variable, and its scope is external. (Recall, however, that the presence of a storage class, an array bound, or a member's level-number causes the VARIABLE attribute to be supplied by default to declarations containing the ENTRY and FILE attributes.)

Parent topic: DECLARE Statements Send feedback about this topic

4.4. Attributes of DECLARE Statements


This section describes, in alphabetical order, the attributes that are permitted in a DECLARE statement. The discussion of each attribute assumes that the attributes have been made complete by the application of defaults, as described in the section Defaults. Each attribute discussed in this section falls into one of the following categories:

Arithmetic or string data attributes, which define arithmetic or string data.


r r r r r r r r r r r r r r

ALIGNED BIGENDIAN BINARY BIT CHARACTER DECIMAL FIXED FLOAT NATIVE NONNATIVE PICTURE REAL UNALIGNED VARYING

Data type attributes, which apply to program data not used for computation.
r r r r r r r r r r r

AREA CONDITION DIMENSION ENTRY EXCLUSIVE FILE LABEL LIKE OFFSET POINTER TYPE

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (129 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Storage class and scope attributes, which control the allocation and storage use for a data variable and define the variable's scope.
r r r r r r r r r r r r r r

AUTOMATIC BASED CONTROLLED CONNECTED DEFINED EXTERNAL GLOBALDEF GLOBALREF INITIAL INTERNAL POSITION REFER STATIC UNION

File description attributes, which can be applied to file constants or may be used in OPEN statements (except ENVIRONMENT, which can be used only in the DECLARE statement).
r r r r r r r r r

DIRECT ENVIRONMENT INPUT KEYED OUTPUT PRINT RECORD SEQUENTIAL STREAM

Entry name attributes, which can be applied to identifiers of entry points. These include:
r r r r r r r r r

BUILTIN ENTRY IRREDUCIBLE OPTIONS(DESCRIPTOR) OPTIONS(NODESCRIPTOR) OPTIONS(VARIABLE) REDUCIBLE RETURNS VARIABLE

Argument-passing attributes, which describe parameters of external procedures. These include:


r r

ANY VALUE

Note: File description attributes specified in a DECLARE statement apply to all openings of the file control block associated with the file constant. For further discussion of these attributes, see the sections Input and Output in the
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (130 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

chapter Language Concepts and OPEN in the chapter Statements.

ALIGNED ANY AREA AUTOMATIC BASED BIGENDIAN BINARY BIT BUILTIN CHARACTER CONDITION CONNECTED CONTROLLED DECIMAL DEFINED DIMENSION DIRECT ENTRY ENVIRONMENT EXCLUSIVE EXTERNAL FILE FIXED FLOAT

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (131 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

GLOBALDEF GLOBALREF INITIAL INPUT INTERNAL IRREDUCIBLE KEYED LABEL LIKE NATIVE NONNATIVE OFFSET OPTIONS(DESCRIPTOR) OPTIONS(NODESCRIPTOR) OPTIONS(VARIABLE) OUTPUT PICTURE POINTER POSITION PRINT READONLY REAL RECORD REDUCIBLE REFER RETURNS

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (132 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

SEQUENTIAL STATIC STREAM TYPE UNALIGNED UNION UPDATE VALUE VARIABLE VARYING

Parent topic: Declarations and Attributes Related information Defaults Input and Output OPEN

Send feedback about this topic

4.4.1. ALIGNED
ALIGNED is a data type attribute that controls the storage boundary of data. ALIGNED is an optional part of the data type specification. Its presence allows the Compiler to align the data on an implementation-defined storage boundary, with the possible side effect that more bits or bytes of storage are used than specified by the declared length. Parent topic: Attributes of DECLARE Statements Related information ALIGNED and UNALIGNED Attributes Bit-String Data

Send feedback about this topic

4.4.2. ANY
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (133 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The ANY attribute specifies that the corresponding argument for a parameter can be of any data type. The ANY attribute is applicable only to the declaration of entry names and is valid only in a parameter descriptor. ANY is not valid as an attribute in a PROCEDURE or ENTRY statement. Parent topic: Attributes of DECLARE Statements Related information ENTRY

Send feedback about this topic

4.4.3. AREA
AREA is a non-computational data type attribute used to define a region of storage in which based variables can be allocated and freed. The format is: AREA[(exp[REFER(variable)])] or AREA(*) For a complete description of area data and the use of the AREA attribute, see the section Area Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Area Data

Send feedback about this topic

4.4.4. AUTOMATIC
Abbreviation: AUTO AUTOMATIC is a storage class attribute that specifies that the declared name is a variable that is allocated storage with each activation of its containing procedure or BEGIN block. The AUTOMATIC attribute is supplied by default to any name of a non-parameter variable that is not a member of a structure and that has no storage class. Parent topic: Attributes of DECLARE Statements Related information Automatic Storage

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (134 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.5. BASED
BASED is a storage class attribute that specifies that the declared name is a based variable. Its format is: BASED[(r)] In the optional form, r is a reference to a locator variable or a locator-valued function that serves as the default (implicit) locator qualifier for unqualified references to the name. Parent topic: Attributes of DECLARE Statements Related information Based Variables

Send feedback about this topic

4.4.6. BIGENDIAN
BIGENDIAN is a data type attribute (applying to Fixed Binary items only) that specifies the internal storage for a data item is MSB first (or MSB "left -to- right"). This attribute is applicable only to Little-Endian machine architectures (such as Intel). For Big-Endian architectures, this attribute is ignored. Example: dcl flag fixed bin (15) static initial (1) bigendian;

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.7. BINARY
Abbreviation: BIN BINARY is an arithmetic data type attribute that specifies that the base is binary. Its format is: BINARY[(p)] The precision p may be supplied with the BINARY attribute or with the FIXED or FLOAT attribute, but it cannot be specified twice. The precision p must be a positive integer. If no precision is specified, a default precision is supplied. For information on the default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If BINARY is specified without FIXED or FLOAT, FIXED is assumed. When used with FIXED, BINARY specifies integer arithmetic values that contain at least p bits. When used with FLOAT, BINARY specifies floating-point arithmetic values that have a mantissa that contains the

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (135 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

equivalent of at least p bits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data

Send feedback about this topic

4.4.8. BIT
BIT is a bit-string data type attribute that identifies a variable as a bit-string variable. Its format is: BIT[(n)] Length n is an extent expression or integer constant, depending on the storage class of the declared name. The length n must be a non-negative integer constant or an expression that evaluates to a non-negative integer. A default length of 1 is supplied if no length is given. For more information on BIT, see the chapter Storage Classes and the section Bit-String Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Storage Classes Bit-String Data

Send feedback about this topic

4.4.9. BUILTIN
BUILTIN is an entry name attribute that indicates that the declared name is a built-in function. Unless an empty argument list is used in a reference to a built-in function having no parameters, the function must be declared with the BUILTIN attribute. BUILTIN can be used to redeclare a built-in function name that was declared as something else in an outer block. The declared name must be one of the names given in the chapter Open PL/I BuiltIns. Parent topic: Attributes of DECLARE Statements Related information Open PL/I BuiltIns Send feedback about this topic

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (136 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

4.4.10. CHARACTER
Abbreviation: CHAR CHARACTER is a character-string data type attribute that identifies a variable as a character-string variable. Its format is: CHARACTER[(n)] Length n is an extent expression or integer constant, depending on the storage class of the declared name. The length n must be a non-negative integer constant or an expression that evaluates to a non-negative integer. A default length of 1 is supplied if no length is specified. For a discussion of storage classes, see the chapter Storage Classes and the section Character-String Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Storage Classes Character-String Data

Send feedback about this topic

4.4.11. CONDITION
Abbreviation: COND CONDITION is an attribute that indicates that the declared name is a condition name. Its format is: CONDITION Condition names can be used only in ON, SIGNAL, or REVERT statements. The default scope of condition name is external. Note that a name that appears with the CONDITION condition in an ON, SIGNAL, or REVERT statement is contextually declared to be a condition name. Parent topic: Attributes of DECLARE Statements Related information ON

Send feedback about this topic

4.4.12. CONNECTED
Abbreviation: CONN The CONNECTED attribute may be used only for parameters. It cannot be specified for a member of a structure and it cannot be specified for CONTROLLED parameters. The CONNECTED attribute asserts that any argument passed to the parameter is in connected storage.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (137 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.13. CONTROLLED
Abbreviation: CTL CONTROLLED is a storage class attribute that specifies a variable whose storage is dynamically allocated and freed in generations. Its format is: CONTROLLED

Parent topic: Attributes of DECLARE Statements Related information Controlled Variables

Send feedback about this topic

4.4.14. DECIMAL
Abbreviation: DEC DECIMAL is an arithmetic data type attribute that specifies that the base is decimal. Its format is: DECIMAL[(p[,q])] The precision p,q (q is optional and represents fractional digits) may be supplied with the DECIMAL attribute or with the FIXED or FLOAT attribute, but it cannot be specified twice. The precision p and the scale q (if specified) must be positive integers. If a precision or scale is not specified, a default is assumed. For more information on default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If DECIMAL is supplied without FIXED or FLOAT, FIXED is the default. If FIXED or FLOAT is specified without BINARY or DECIMAL, DECIMAL is the default. When used with FIXED, DECIMAL specifies fixed-point arithmetic values that contain at least p decimal digits. If q is specified, p minus q digits are integral digits and q digits are fractional digits. If q is omitted, q = 0 is assumed. These values are integers containing at most p decimal digits. When used with FLOAT, DECIMAL specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p decimal digits. In this case, q cannot be specified. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (138 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.15. DEFINED
Abbreviation: DEF DEFINED is a storage class attribute that specifies that the declared name is a defined variable that shares storage with a basis variable. Its format is: DEFINED(r) where r is the basis variable. Parent topic: Attributes of DECLARE Statements Related information Defined Variables

Send feedback about this topic

4.4.16. DIMENSION
Abbreviation: DIM DIMENSION is an attribute that specifies that a declared name is an array and defines the number and extent of its dimensions. Its format is: DIMENSION(b1[,b2]) Each b represents one bound pair, which specifies the number of elements in a single dimension of the array. Each bound pair specifies an optional lower bound (lb) and a requisite upper bound (hb) for that dimension. A bound pair can be specified as follows.

The asterisk format of a bound pair, when used to define a parameter for a procedure or function, specifies that both the upper and lower bound of this dimension are to be taken from the corresponding array argument. If one bound pair is specified as asterisks, all bound pairs must be specified as asterisks. This format specifies the minimum and maximum subscripts that can be used for the dimension. lb is an extent expression or optionally signed integer constant, depending on the storage class of the array, which specifies the lower bound of the dimension. Like lb, hb is either an extent expression or an optionally signed integer constant, depending on the storage class. It specifies the upper bound of the dimension. This format specifies only the upper bound of the dimension. The lower bound is assumed to be 1.

lb:hb

hb

For example: DECLARE X(5) FLOAT;

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (139 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

DECLARE Y DIMENSION(5) FLOAT; In this example, both X and Y are arrays of five floating-point values. The DIMENSION attribute is normally written immediately after the variable's name and is written without the DIMENSION keyword. When specified with the FILE or ENTRY attributes, DIMENSION causes the associated name to become a variable rather than a named constant. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.17. DIRECT
DIRECT is a file description attribute that indicates that a file can be accessed nonsequentially, that is, by key or by relative record number. The DIRECT attribute may be given either in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.18. ENTRY
ENTRY is a data type attribute that declares a constant or variable whose value is an entry point, and describes the attributes of the parameters, if any, that are declared for the entry point. Its format is: ENTRY [([parameter-list])] where parameter-list is: ()|parameter-descriptor[,parameter-descriptor]... where parameter-descriptor is: attribute[attribute] ... |*|,|structure-descriptor where structure-descriptor is: 1 [attribute] ... ,level[attribute] ... [,level[attribute]] ... An arbitrary parameter-descriptor can be indicated by use of an asterisk ( * ) or by a blank parameter-descriptor position, as indicated by the commas. For example, ENTRY(FIXED BIN, , FLOAT /* Three parameters. The second is of any data type. */

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (140 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

ENTRY(FIXED BIN, * ,FLOAT)/* Three parameters. The second is of any data type. */ ENTRY(, , ,) /* Four parameters of any data type. */ ENTRY() /* No parameters allowed. */ ENTRY /* Any number of parameters is allowed. */ The ENTRY attribute without the RETURNS option has an implicit RETURNS data type. It is determined by the In rule. External entries with the implicit RETURNS can be called as functions or procedures. Open PL/I does not require that if any entry statement in a multiple entry procedure has a RETURNS option, then all entries must have one. ENTRY can be used with or without the VARIABLE attribute. Used without the VARIABLE attribute, the ENTRY attribute declares a constant that is the name of an external procedure. In this case, each p is a list of attributes that is either identical to the attributes specified for the corresponding parameter in the external procedure, or is ANY. For example: DECLARE E ENTRY(FIXED BINARY(15), POINTER); In this example, E refers to a procedure that accepts a fixed binary and a pointer argument. Used with the VARIABLE attribute, the ENTRY attribute specifies that the declared name is a variable of the data type entry, which can be assigned any procedure name. When the entry variable is called, it must hold an entry value that designates a PROCEDURE statement whose parameters have attributes that are identical (unless the attribute is ANY) to the corresponding attributes given by p1, p2, and so forth. Using the declaration for E from the previous example, a compatible procedure declaration would be as follows: E: PROCEDURE(X,Y); DECLARE X FIXED BINARY(15); DECLARE Y POINTER; If a PROCEDURE statement has one or more parameters that are structures, the ENTRY attribute used to declare the procedure name must have a set of attributes for each member of the structure, including all substructures, as shown in the following example: DECLARE E ENTRY(1,2 FIXED, 2 FLOAT, POINTER); In the previous example, E is a procedure having two parameters; the first parameter is a structure with two members, and the second parameter is a pointer. The parameter attributes given in the ENTRY attribute include the level numbers and attributes of all members, as well as the level number and attributes of the parameter structure. All string lengths or array bounds given in an ENTRY attribute must be exactly the same as those given in the parameters of the PROCEDURE statement. Programs that violate this rule may produce unpredictable results. The ENTRY attribute can be used with the ANY, OPTIONS(VARIABLE), RETURNS(returns_descriptor), and VALUE options according to the following format: DECLARE entry_nameENTRY[(parameter_descriptor[VALUE])] [OPTIONS(VARIABLE)] [RETURNS(returns_descriptor)]; The RETURNS attribute is required for entry points that are invoked by function references and is invalid for procedures invoked by CALL statements. Parameter descriptors are not allowed if the ENTRY attribute is within a RETURNS descriptor.
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (141 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The parameter descriptor lists attributes for each parameter and must include either the data type of the parameter or the attribute ANY. The VALUE attribute indicates that the corresponding argument is to be passed by immediate value. The OPTIONS(VARIABLE) option indicates that the specified external procedure can be invoked with a variable number of arguments. The following options can be specified as part of the OPTIONS(VARIABLE) attribute when declaring an ENTRY:

ASSEMBLER NOMAP [map-list] COBOL NOMAPIN [map-list] FORTRAN NOMAPOUT [map-list] INTER NOEXECOPS TASK RETCODE

The RETURNS(retums_descriptor) option gives the data type attributes of the function value returned for an entry invoked as a function reference. The VARIABLE attribute is not valid in a parameter descriptor or in a RETURNS descriptor. The VALUE attribute can be used in an ENTRY declaration in conjunction with the data types Fixed Binary, Pointer, Character, Aligned Bit, Entry, or Float Binary. For more information, see the section VALUE. If the ANY attribute is included as a parameter descriptor, the argument that corresponds to that parameter descriptor can be of any data type. If the argument is a variable, its address is passed to the called procedure. If the argument is a constant or an expression, a dummy argument is created and its address is passed to the called procedure. The following conversions take place when creating the dummy argument:

Written Data Type

Dummy Data Type

Bit (Unaligned) Fixed Binary or Fixed Decimal(p,O) Char Varying

Bit(n) Aligned, where n is the length of the string Fixed Binary(31) Char(n), where n is the length of the string

For more information, see the chapter Storage Classes and your Open PL/I User's Guide. The OPTIONS(VARIABLE) attribute is used to indicate that it is valid for a discrepancy to exist between the number of parameter descriptors in the declaration of the procedure and the number of arguments in the argument list used to call the procedure. The following rules apply when using the OPTIONS(VARIABLE) option:

If a procedure is called with more arguments than there are parameter descriptors, the trailing arguments are passed using the attributes of the last parameter descriptor. In this case, use of at least one parameter descriptor is required. If a procedure is called with some arguments omitted, a null pointer is passed to the called routine in place of the missing argument. (The null pointer indicates an omitted argument.) An argument is considered to be omitted if two commas are found adjacent to one another in a call to a procedure, or if a comma comes after the left parenthesis or before the right parenthesis; that is, ( , a, ) indicates two missing arguments.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (142 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

If a procedure is called with more arguments than there are parameter descriptors, and the trailing arguments are omitted (as indicated by adjacent commas), a null pointer is passed for each of the omitted arguments.

The following examples show how the ENTRY attribute can be used with the VALUE, ANY, OPTIONS(VARIABLE), and RETURNS(retums_descriptor) options. For a further description of these options, refer to each option by name within this chapter. The following example causes the value of A to be converted to Fixed Binary(31) and the immediate value (25) to be passed directly to P5, followed by an immediate value representing the address of A: DECLARE P5 ENTRY (FIXED BIN(31) VALUE, POINTER VALUE), A FIXED BIN(15), B POINTER; A = 25; B = ADDR (A); CALL P5(A,B); The following example illustrates the use of the ENTRY attribute with the OPTIONS( VARIABLE) and ANY options: DECLARE P1 ENTRY (FIXED BINARY(15), ANY) OPTIONS(VARIABLE), A FIXED BINARY(15), B FLOAT BINARY(23), C CHARACTER(1); CALL P1(A, B); CALL P1(A, C, B); In the previous example, the second parameter descriptor is declared as ANY. In the first call to P1, B, a Float Binary (23) variable is the second argument passed; in the second call to P1, C, a Char(1) variable is passed. In both calls, the variable is passed by reference. Since the OPTIONS(VARIABLE) attribute is used, the second call to P1 passes argument three, B, using the attribute for parameter descriptor two, ANY. In the second call, the variable B is passed by reference. The following example illustrates a procedure called with some arguments omitted. DECLARE P2 ENTRY (FIXED BINARY(15), FIXED BINARY(15), FIXED BINARY(15)) OPTIONS(VARIABLE), (A,B) FIXED BINARY(15); CALL P2(A, ,B); In the previous example, the arguments to be passed are A, a missing argument, and B. This configuration causes the address of A to be passed, followed by a null value, followed by the address of B. The following example illustrates a procedure called with more arguments than there are parameter descriptors: DECLARE P3 ENTRY (FIXED BINARY(15),FIXED BINARY(15)) OPTIONS(VARIABLE), (A,B) FIXED BINARY(15), C FLOAT BINARY(31); CALL P3 (A, B, ,);
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (143 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

CALL P3 (A, B, C); In the previous example, the first call to P3 is declared with two parameter descriptors and called with four arguments, the last two being null. The addresses of the last two arguments will be represented by null values. The second call to P3 passes C as a Fixed Binary(15), since it is a trailing argument and is passed with the attribute of the last parameter descriptor. This configuration requires that C be converted from Float Binary to Fixed Binary, and that the address of the resulting temporary be passed. The following example illustrates constants and expressions being passed with the ANY option: DECLARE P4 ENTRY (ANY,ANY), ( A, B ) FIXED BINARY(15); CALL P4( 3, 'ABC'); CALL P4( '1'B, AB ); In the first call to P4, the constant 3 will be converted to Fixed Binary(31) and the address of the temporary variable containing the converted value will be passed as the first argument; the character-string constant 'ABC' will be converted to Character(3) and its temporary address passed as the second argument. In the second call to P4, the bitstring constant '1' B will be converted to Bit(1) Aligned, AB will be converted to Fixed Binary(31), and the respective addresses of the temporaries will be passed to P4. The following example illustrates the use of the RETURNS(retums_descriptor) option: DECLARE F ENTRY(FIXED) RETURNS(POINTER); DECLARE G ENTRY(FLOAT) RETURNS(CHARACTER(32)VARYING); In this example, F is declared as the name of a function procedure that returns pointer values. G is declared as the name of a function procedure that returns varying character-string values whose maximum length is 32 characters. Parent topic: Attributes of DECLARE Statements Related information Storage Classes

Send feedback about this topic

4.4.19. ENVIRONMENT
Abbreviation: ENV The ENVIRONMENT attribute and its options specify many record characteristics that are not part of the PL/I language. Its format is: ENVIRONMENT(optionslist) options-list can contain any of a number options specifying record characteristics. For example, ENVIRONMENT(VSAM KEYLOC(1) KEYLENGTH(12)); The ENVIRONMENT attribute is not supported for use with a STREAM file.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (144 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Parent topic: Attributes of DECLARE Statements Related information Record I/O

Send feedback about this topic

4.4.20. EXCLUSIVE
Abbreviation: EXCL The EXCLUSIVE attribute specifies that the records in a file can be locked when accessed by one process to prevent access by another process. When the EXCLUSIVE attribute is used, the entire file is locked. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.21. EXTERNAL
Abbreviation: EXT EXTERNAL is a scope attribute that specifies that the declared name has external scope. This means that all declarations of this name anywhere in the program that also have the EXTERNAL attribute identify the same object. The EXTERNAL attribute can be used only in the declaration of variables whose storage class is STATIC or CONTROLLED. (It can be redundantly specified for variables of storage classes GLOBALDEF and GLOBALREF, which are implicitly EXTERNAL STATIC.) If EXTERNAL is specified for a variable and no storage class attribute is specified, STATIC is supplied by default. Its format is: EXTERNAL[(global_name)] global_name is either a character-string constant or a %REPLACE name for a character string constant. global_name is used by the linker when references are made to the entry. Open PL/I makes no restrictions on the contents of global_name, but the underlying operating system may have restrictions. EXTERNAL must be specified when the entry is declared in another module. EXTERNAL(global_name) is specified as an option either on a PROCEDURE statement or on an ENTRY statement. By using the EXTERNAL(global_name) option, an alternative name can be specified for an external entry constant. Instead of the usual entry constant name, the alternative name (global_name) is used to invoke the procedure at the entry point. OZS: PROCEDURE; DECLARE PROC1 ENTRY; DECLARE ALSO_PROC1 ENTRY EXTERNAL('PROC1'); DECLARE PROC2 ENTRY EXTERNAL('ILL.EGAL'); CALL PROC1; CALL ALSO_PROC1; CALL PROC2; END OZS;

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (145 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

/*======== A SEPARATE MODULE ========*/ PROC1: PROCEDURE; PROC2: ENTRY EXTERNAL('ILL.EGAL'); END PROC1; In this example, the program declares explicitly the entry constants PROC1 and PROC2. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.22. FILE
FILE is a data type attribute. Used without the VARIABLE attribute, it specifies that the declared name is a file identifier having external scope and an associated file control block that can be used to perform I/O on files and devices known to the operating system. In this case, the EXTERNAL attribute and any of the file description attributes RECORD, STREAM, INPUT, OUTPUT, UPDATE, KEYED, DIRECT, SEQUENTIAL, and PRINT may also be specified. Any file description attributes specified in the declaration are merged with attributes supplied by the OPEN statement or attributes implied by the I/O statement that implicitly opens the file control block. Used with the VARIABLE attribute, FILE specifies that the declared name is a file variable that can be assigned file values. In this case, the file description attributes cannot be supplied because a file variable has no associated file control block until a file value is assigned to it. File description attributes are attributes of a file control block and are not attributes of a file value or file variable. Some attributes for a name declared implicitly can be determined from the context in which the name appears. These cases are called contextual declarations. A name that appears in a FILE option, or in an ON, SIGNAL, or REVERT statement for a condition that requires a file name, is given the FILE attribute. For example, OPEN FILE(F); WRITE FILE(W) FROM(BUF); READ FILE(R) INTO(BUF); CLOSE FILE(C); In all four above cases the names used with the FILE option will be implicitly declared as having File data type. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.23. FIXED
FIXED is an arithmetic data type attribute that defines a fixed-point arithmetic variable. Its format is: FIXED[(p[,q])]

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (146 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The precision p,q (q is optional and represents fractional digits) may be supplied with this attribute or with the BINARY or DECIMAL attribute, but it cannot be specified twice. The precision p and the scale q (if specified) must be positive integers. If a precision or scale is not specified, a default is assumed. If FIXED is specified without BINARY or DECIMAL, DECIMAL is assumed. For details on precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. When used with BINARY, FIXED specifies integer arithmetic values that contain at least p bits. In this case, q must not be specified. When used with DECIMAL, FIXED specifies fixed-point arithmetic values that contain at least p decimal digits. If q is specified, p minus q digits are integral digits and q digits are fractional digits. If q is omitted, q = 0 is assumed. These values are integers containing at least p decimal digits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data

Send feedback about this topic

4.4.24. FLOAT
FLOAT is an arithmetic data type attribute that defines a floating-point arithmetic value. Its format is: FLOAT[(p)] The precision p may be supplied with this attribute or with the BINARY or DECIMAL attribute, but it cannot be specified twice. The precision p must be a positive integer. If a precision is not specified, a default precision is assumed. for information on the Open PL/I default precisions, see your Open PL/I User's Guide and the section DEFAULT in the chapter Statements. If FLOAT is specified without BINARY or DECIMAL, DECIMAL is the default. If BINARY or DECIMAL is supplied without FIXED or FLOAT, FIXED is the default. When used with BINARY, FLOAT specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p bits. When used with DECIMAL, FLOAT specifies floating-point arithmetic values whose mantissa contains the equivalent of at least p decimal digits. Parent topic: Attributes of DECLARE Statements Related information DEFAULT Arithmetic Data

Send feedback about this topic

4.4.25. GLOBALDEF
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (147 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

GLOBALDEF is a storage class and scope attribute that declares an external variable or external file constant and causes storage to be allocated for the variable or constant. Its format is: GLOBALDEF [(name)] where name is an identifier that is accepted as legal syntax for compatibility with other Open PL/I extensions, but is ignored, having no effect. For variables, the GLOBALDEF attribute implies the EXTERNAL and STATIC attributes. For file constants, it implies the EXTERNAL attribute. A given variable or file constant may be declared with the GLOBALDEF attribute in only one procedure. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.26. GLOBALREF
GLOBALREF is a storage class and scope attribute that declares a global symbol, which is defined in an external procedure either with the GLOBALDEF attribute or, if the external procedure is written in another programming language, with its equivalent in that language. Its format is: GLOBALREF [(name)] where name is an identifier that is accepted as legal syntax for compatibility with other Open PL/I extensions, but is ignored, having no effect. The GLOBALREF attribute implies the EXTERNAL and STATIC attributes. A variable may be declared with the GLOBALREF attribute in as many procedures as desired. Unlike GLOBALDEF, GLOBALREF does not cause actual storage to be allocated for the external variable, but allows access to the storage that was allocated by some other external procedure. If GLOBALREF is present, any INITIAL attribute for the variable is ignored. P1: PROCEDURE; DECLARE XVAR FIXED BIN(15) GLOBALDEF; XVAR = 23; CALL P2; . . . P2: PROCEDURE; DECLARE XVAR FIXED BIN(15) GLOBALREF; IF XVAR > 0 THEN XVAR = 100; . . .

In this example, XVAR is declared with the GLOBALDEF attribute in procedure P1 and is assigned storage as a result. The value 23 is assigned to XVAR. Procedure P2 has declared XVAR with the GLOBALREF attribute and will access the same memory location allocated by P1 . Procedure P2 can test and/or change the value of XVAR. Parent topic: Attributes of DECLARE Statements Send feedback about this topic
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (148 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

4.4.27. INITIAL
Abbreviation: INIT INITIAL is a storage class attribute that specifies the initial value of a variable or member of a structure. The INITIAL attribute has two formats. The first specifies an initial constant, expression, or variable whose value is assigned to a variable when storage is allocated to it. The second format specifies that the CALL option invokes a procedure to perform initialization at allocation. The variable is initialized by assignment during the execution of the called routine, rather than by the routine being invoked as a function that returns a value to the point of invocation. The formats of the INITIAL attribute are: Format 1: INITIAL(item[,item]) where item is: *|constant|variable|expression|iteration-spec where iteration-spec is: (iteration-factor) iteration-item where iteration-item is: *|constant|variable|expression where iteration-factor is: *|expression where constant is: arithmetic-constant|bit-constant|character-constant| entry-constant1 label-constant Note: Open PL/I supports the ANS PL/I Subset G specification for the INITIAL attribute, not the full mainframe PL/ I specification. In the context of item or iteration-item, asterisk ( * ) specifies that the element is to be left uninitialized. In the context of iteration-factor, asterisk (* ) specifies that the entire array is to be initialized with the iteration-item. For static variables, any value specified in an INITIAL attribute is assigned at the time the program is first loaded into memory for execution. For automatic variables, which are allocated at each activation of the declaring block, any specified initial value is assigned at the time of each allocation. For based and controlled variables, which are allocated at the execution of ALLOCATE statements, any specified initial value is assigned at the time of each allocation.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (149 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

The INITIAL attribute may not be used with variables of storage classes other than those mentioned above. Only constant values with no operations can be specified in the INITIAL attribute for static variables, with the following exceptions:

The NULL() built-in function can be used to initialize a static pointer variable. Expressions containing concatenated string constants can be used to initialize static string variables. For example: DECLARE STRING CHAR(5) STATIC INIT ('LIA' || 'NT');

Format 2: INITIAL CALL entry(arg[,arg]) The INITIAL call cannot be used to initialize static data.

Examples of the INITIAL Attribute

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.27.1. Examples of the INITIAL Attribute


The following example will initialize all elements of 3x3 matrix A with the exception of its diagonal elements A (1,1), A (2,2), and A(3,3): DECLARE A(3,3) FIXED BIN INIT(*,(3)0,*,(3)0,*); The following example will initialize all elements of array B to the value of the expression (X+10 ) where X is a procedure parameter. SUB; PROCEDURE(X); DECLARE X FIXED BIN(15); DECLARE B(5) FLOAT BIN INIT((HBOUND(B,1))(X+10)); The following example demonstrates the usage of asterisk repeat factor and will initialize the entire array Z to the value of 1.0. SUB1: PROCEDURE(DIM); DECLARE DIM FIXED BIN(15); DECLARE Z(DIM) FLOAT BIN(23) INIT((*)1.0); The INITIAL CALL is used to initialize automatic, based, or controlled variables by calling an external entry. The following is an example.

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (150 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

TEST: PROCEDURE OPTIONS(MAIN); /* Initialize all elements of array TEN */ DECLARE TEN(10) FIXED BIN(15) INIT CALL INITIALIZE(ADDR(TEN),HBOUND(TEN,1)); INITIALIZE: PROCEDURE(P,DIM); DECLARE P DIM DECLARE I ARRAY(1000)

POINTER, FIXED BIN(15); FIXED BIN, FIXED BIN(15) BASED;

DO I = 1 TO DIM; P->ARRAY(I)=75; END; END INITIALIZE; END TEST;

Parent topic: INITIAL Send feedback about this topic

4.4.28. INPUT
INPUT is a file description attribute that specifies that a file will be used for input. The INPUT attribute may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. File description attributes specified in a DECLARE statement apply to all openings of the file control block associated with the file constant. Parent topic: Attributes of DECLARE Statements Related information Input and Output OPEN

Send feedback about this topic

4.4.29. INTERNAL
Abbreviation: INT INTERNAL is a scope attribute that limits the scope of a variable to the block in which it is defined. The INTERNAL attribute may be given with any storage class attribute or to parameters, but it has no significance
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (151 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

since these variables always have internal scope. If STATIC is used without INTERNAL or EXTERNAL, INTERNAL is the default. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.30. IRREDUCIBLE
Abbreviation: IRRED IRREDUCIBLE is an attribute sometimes used by IBM mainframe PL/I programs. It is not needed by Open PL/I. It is simply parsed and otherwise ignored. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.31. KEYED
KEYED is a file description attribute that indicates that records in a specified file may be accessed randomly. The KEYED attribute implies the RECORD attribute. KEYED may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN

Send feedback about this topic

4.4.32. LABEL
LABEL is a data type attribute that specifies label values. When used in the declaration of a name, it specifies that the declared name is a label variable. When used in an ENTRY attribute, it specifies that the corresponding parameter is a label variable, and when used in a RETURNS attribute, it specifies that the procedure returns label values. For a discussion of label values, see the section Label Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Label Data

Send feedback about this topic


http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (152 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

4.4.33. LIKE
LIKE specifies that the variable being declared has the same structure as the referenced variable. Its format is: LIKE reference where reference is a reference to a structure variable. The variable being declared must be a structure variable. LIKE causes it to have exactly the same members, in name and attributes, as the referenced structure variable. Only the level numbers are changed as needed to adapt to the variable being declared. In the following example, structure members are duplicated from one declaration to another by way of the LIKE attribute: DECLARE 1 TEMPLATE BASED, 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); DECLARE 1 EMPLOYEE_INFO(1000) LIKE TEMPLATE; Duplication of the members from TEMPLATE expands the declaration of EMPLOYEE_INFO, with the result that the declaration of EMPLOYEE_INFO is equivalent to: DECLARE 1 EMPLOYEE_INFO(1000), 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); The referenced variable can be a major or a minor structure. It may be qualified, but may not be pointer-qualified. The following restrictions apply to the referenced variable:

It must be known in the block containing the LIKE attribute specification. It cannot be subscripted. It cannot contain a REFER variable. Neither the referenced variable nor any of its substructures can be declared with the LIKE attribute. It cannot be a substructure of a structure declared with the LIKE attribute.

The function of the LIKE attribute is similar to that of the TYPE attribute . With LIKE, the storage class of the referenced structure is not carried over to the created structure (same as TYPE). However, neither are the alignment attributes and/or dimensions of the referenced variable carried over (unlike TYPE). Only the alignment and dimensions of substructures and elements of the referenced variable are carried over. Note: Because the UNALIGNED attribute is not carried forward with LIKE, two LIKE structures could have differing alignment characteristics and sizes because of structure mapping conventions.

Parent topic: Attributes of DECLARE Statements


http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (153 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Related information TYPE

Send feedback about this topic

4.4.34. NATIVE
NATIVE is a data type attribute (applying to Fixed Binary items only) that specifies the internal storage for the data item is LSB first (or MSB "right -to- left"). This attribute is applicable only to Little-Endian machine architectures (such as Intel), and is the default if not specified. For Big-endian architectures, this attribute is ignored. Example: dcl flag fixed bin (15) static initial (1) native;

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.35. NONNATIVE
NONNATIVE is equivalent to BIGENDIAN. Example: dcl flag fixed bin (15) static initial (1) nonnative;

Parent topic: Attributes of DECLARE Statements Related information BIGENDIAN

Send feedback about this topic

4.4.36. OFFSET
The OFFSET attribute defines a locator data type used to specify the relative location of a based variable within an area. The format is: OFFSET[(areavariable)] For a complete description of offset data and the use of the OFFSET attribute, see the sections Offset Data and Area Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (154 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Related information Offset Data Area Data

Send feedback about this topic

4.4.37. OPTIONS(DESCRIPTOR)
OPTIONS(DESCRIPTOR) is an entry name attribute. It specifies that argument descriptors will be passed to this entry by callers. This is the default for entry names. Argument descriptors are used to pass specific details about actual parameters in cases where parameter declarations contain CHAR(*) or DIMENSION(*) attributes. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.38. OPTIONS(NODESCRIPTOR)
OPTIONS(NODESCRIPTOR) is an entry name attribute. It specifies that argument descriptors will not be passed to this entry by callers. Argument descriptors are used to pass specific details about actual parameters in cases where parameter declarations contain CHAR(*) or DIMENSION(*) attributes. The OPTIONS(NODESCRIPTOR) attribute is normally used to suppress the generation and passing of the descriptor(s) to a non-PL/I procedure. Note: OPTIONS(ASM) and OPTIONS(COBOL) are equivalent to OPTIONS(NODESCRIPTOR).

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.39. OPTIONS(VARIABLE)
OPTIONS(VARIABLE) is an entry name attribute that indicates, for an ENTRY descriptor, that a specified external procedure can be invoked with a variable number of arguments; a discrepancy may exist between the number of parameter descriptors in the declaration of the procedure and the number of arguments in the argument list used to call the procedure. OPTIONS(VARIABLE) attribute is parsed and is otherwise ignored. It is an invalid attribute for a PROCEDURE or ENTRY statement, as opposed to the ENTRY attribute. Parent topic: Attributes of DECLARE Statements Related information ENTRY

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (155 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.40. OUTPUT
OUTPUT is a file description attribute that indicates that data should be written to, and not read from, the associated file or device. The OUTPUT attribute may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN

Send feedback about this topic

4.4.41. PICTURE
Abbreviation: PIC PICTURE is a data type attribute that specifies pictured values. Its format is: PICTURE'p' The picture 'p' contains an image of the data and specifies the editing to be performed each time a value is assigned to a pictured variable. It also governs the conversion of pictured values to fixed-point decimal values. For a discussion of pictured data and the picture characters, see the section Picture Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Picture Data

Send feedback about this topic

4.4.42. POINTER
Abbreviation: PTR POINTER is a data type attribute that specifies pointer values. A pointer value is the address of a variable and is discussed in the section Pointer Data in the chapter Data Types. Parent topic: Attributes of DECLARE Statements Related information Pointer Data

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (156 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.43. POSITION
Abbreviation: POS POSITION is an attribute that is used in conjunction with the DEFINED attribute. It specifies the bit or character within the basis variable at which the defined variable is to begin. Its format is: POSITION(expression) where expression is an integer expression that specifies the position relative to the start of the basis variable. The range of the expression is from 1 to n, where n is defined as: n = basis_length defined_length+1 where basis_length is the length of the basis variable in bits or characters and defined_length is the length of the defined variable in bits or characters. Both the defined variable and the basis variable must be fixed-length bit strings, fixed-length character strings, pictured variables, or aggregates containing any of these data types. In the following example, the two DO-groups accomplish the same purpose. The second makes use of the POSITION attribute: DECLARE X CHARACTER(200); DECLARE Y CHARACTER(1) DEF X POS(I); DO I = 1 to 200; IF SUBSTR(x,i,1) = '?' THEN CALL ERROR(); DO I = 1 to 200; IF Y = '?' THEN CALL ERROR();

/* Uses position attributes */

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.44. PRINT
PRINT is a file description attribute used to declare a print file. PRINT may be given in the declaration of a file constant or in an OPEN statement, but it must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (157 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

OPEN

Send feedback about this topic

4.4.45. READONLY
The READONLY attribute is parsed and is otherwise ignored. This is a compatibility feature to allow Open PL/I programs written for other systems to compile without error. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.46. REAL
REAL is an arithmetic data type attribute. It specifies that the associated variable is used for real numbers (that is, single-part numbers, as opposed to complex). Arithmetic variables are assumed to be REAL by default. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.47. RECORD
RECORD is a file description attribute that indicates that data in an input or output file is made up of separate records, and that the file will be processed by record I/O statements. RECORD may be given in the declaration of a file constant or may be given in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN

Send feedback about this topic

4.4.48. REDUCIBLE
Abbreviation: RED REDUCIBLE is an attribute sometimes used by IBM mainframe PL/I programs. It is not needed by Open PL/I. It is simply parsed and otherwise ignored. Parent topic: Attributes of DECLARE Statements

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (158 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.49. REFER
REFER is an attribute of a based structure that specifies that the value of one member is used to determine the amount of storage space allocated for another member of the same structure. Its format is: expressionREFER(variable) where expression is evaluated and converted to Fixed Binary (15) and is the initial extent when the based structure is allocated. Variables used in the expression being evaluated as operands must not belong to the member containing the REFER attribute. variable must be a variable contained by the structure being allocated and defined prior to the extent whose size it determines. For example: DECLARE 1 STRUC BASED(P), 2 I FIXED BINARY, 2 A CHARACTER(20 REFER(I)); Multiple REFER attributes are allowed in the declaration of a structure. Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.50. RETURNS
RETURNS is an entry name attribute that specifies that the entry value designates a function procedure that returns a value of data type t, where t is a list of attributes that specify a data type. Its format is: RETURNS[(t)]; For example: DECLARE F ENTRY(FIXED) RETURNS(POINTER); DECLARE G ENTRY(FLOAT) RETURNS(CHARACTER(32)VARYING); In this example, F is declared as the name of a function procedure that returns pointer values. G is declared as the name of a function procedure that returns varying character-string values whose maximum length is 32 characters. Any string length given in a RETURNS attribute must be an integer constant. The only attributes that can be given in a RETURNS attribute are data type attributes. DIMENSION or level numbers cannot be given, because functions cannot return arrays or structures. Parent topic: Attributes of DECLARE Statements Related information ENTRY

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (159 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

Send feedback about this topic

4.4.51. SEQUENTIAL
Abbreviation: SEQL SEQUENTIAL is a file description attribute that indicates that records in the file will be accessed sequentially. SEQUENTIAL may be given in the declaration of a file constant or in an OPEN statement. It must not be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN

Send feedback about this topic

4.4.52. STATIC
STATIC is a storage class attribute that specifies that the storage for the declared variable is allocated by the Compiler and/or linker prior to program execution and remains allocated throughout program execution. The default attribute is AUTOMATIC. Parent topic: Attributes of DECLARE Statements Related information Static Storage

Send feedback about this topic

4.4.53. STREAM
STREAM is a file description attribute that indicates that the file consists of ASCII characters and will be processed using the GET and PUT statements. The STREAM attribute may be given in the declaration of a file constant or in an OPEN statement, but it cannot be specified in the declaration of a file variable. Parent topic: Attributes of DECLARE Statements Related information OPEN

Send feedback about this topic

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (160 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

4.4.54. TYPE
The TYPE attribute allows a declaration to inherit structure members and attributes from another declaration. It has the following format, where reference is a reference to a variable: TYPE(reference) If, for example, a variable INTEGER is declared as fixed binary, another variable that needs to be declared as fixed binary can be declared as TYPE (INTEGER) instead. For example: DECLARE INTEGER DECLARE CODE FIXED BIN(31); TYPE(INTEGER); /* TYPE DEFINITION */ /* TYPED VARIABLE */

In this example, Open PL/I copies the attributes from INTEGER to CODE, which makes the declaration of CODE become the following: DECLARE CODE FIXED BIN(31);

In the previous example, INTEGER is referred to as a type definition and CODE is referred to as a typed variable. A type definition is a normal variable declaration. It can be given the based storage class, because storage will not be allocated for the type definition. In the following example, structure members are duplicated from one declaration to another by way of the TYPE attribute: DECLARE 1 TEMPLATE BASED, /* TYPE DEFINITION */ 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); DECLARE EMPLOYEE_INFO TYPE(TEMPLATE); /* TYPED VARIABLE */ Duplication of the members from TEMPLATE expands the declaration of EMPLOYEE_INFO, with the result that the declaration of EMPLOYEE_INFO is now: DECLARE 1 EMPLOYEE_INFO 2 NAME CHAR(45), 2 SALARY FIXED BIN(15), 2 EMP_NO FIXED BIN(15); The TYPE attribute can be used in any of the following locations:

Within a variable declaration. Within a parameter declaration. As a parameter description within the explicit declaration of an ENTRY constant or ENTRY variable. Within a RETURNS option of a PROCEDURE or ENTRY statement. As a RETURNS attribute of an ENTRY declaration.

The following example illustrates all uses of the TYPE attribute:

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (161 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

/*----------- TYPE DEFINITION -----------*/ /* (LINE MAY ALSO BE USED AS A VARIABLE) */ DECLARE LINE CHAR(80) VARYING; /*---------------------------------------*/ /* VARIABLE DECLARATION */ DECLARE FORMAT_LINE TYPE(LINE); /* PARAMETER DECLARATION */ DECLARE PARAM TYPE(LINE); /* PARAMETER DESCRIPTOR */ DECLARE WRITE_LINE ENTRY(TYPE(LINE)); /* RETURNS OPTION IN PROCEDURE STATEMENT */ GET_LINE: PROC RETURNS(TYPE(LINE)); /* RETURNS OPTION IN ENTRY STATEMENT */ READ_LINE: ENTRY RETURNS(TYPE(LINE)); /* RETURNS ATTRIBUTE IN DECLARE STATEMENT */ DECLARE GET_LINE ENTRY RETURNS(TYPE(LINE)); A typed variable can inherit only the following attributes from its type definition (storage class is not inherited):

ALIGNED BINARY BIT CHARACTER DECIMAL ENTRY FILE FIXED FLOAT LABEL PICTURE OPTIONS POINTER RETURNS

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (162 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

UNALIGNED UNION VARIABLE VARYING string length arithmetic precision array dimensions.

TYPE Attribute Extensions TYPE and Extent Expressions Using the TYPE Attribute Examples of the TYPE Attribute

Parent topic: Attributes of DECLARE Statements Send feedback about this topic

4.4.54.1. TYPE Attribute Extensions


The TYPE attribute can be used to declare a function that returns an aggregate (that is, array or structure) result. For example: /* TYPE DEFINITION */ DECLARE ARRAY(10) CHAR(80), 1 STRUCTURE, 2 LEVEL1 BINARY(15) 2 LEVEL2 BINARY(15) DECLARE FUNCTION1 ENTRY RETURNS(TYPE(ARRAY)); FUNCTION2 ENTRY RETURNS(TYPE(STRUCTURE)); Note: All extents in the type definition of the function must have constant values. For example, the dimension attribute of ARRAY (10) in the preceding declaration could not be a variable. The TYPE attribute also allows an aggregate variable to be passed by value in one of the following two situations:

When a typed variable (enclosed in parentheses) is used in an argument list (see the following example).

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (163 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

When a function reference used as an argument has a RETURNS value that is declared with the TYPE attribute (see the following example). DECLARE XARR(10) FIXED BIN(15) YYR TYPE( XARR ), RTE ENTRY( TYPE(XARR) ), FCA ENTRY RETURNS( TYPE(XARR) ); CALL RTE( (XARR) ); /* CASE 1 */ CALL RTE( (YYR) ); /* CASE 1 */ CALL RTE( (FCA()) ); /* CASE 2 */

The parameter in the called routine must have the same TYPE attribute as the argument. In the above example, RTE's parameter has the attribute TYPE (XARR) (see the third line). This TYPE attribute is the same TYPE attribute that is used by the arguments in the subsequent calls to RTE (see the last 3 lines). All extents in a type definition must have constant values when an aggregate variable is passed by value. For example, in the preceding program fragment, XARR. could not be declared as: DECLARE N FIXED BINARY(31) INIT(10); DECLARE XARR(N) FIXED BIN(15), . . . Dimensions (array bounds) can be specified on either the type definition or the typed variable, but not on both. For example, the following declaration of an array of arrays is invalid: DECLARE XXX(10) CHAR(80), /* VALID */ YYY TYPE( XXX ), /* VALID */ ZZZ(10) TYPE( XX ); /* INVALID -- ARRAY OF ARRAYS */

Parent topic: TYPE Send feedback about this topic

4.4.54.2. TYPE and Extent Expressions


Any extent expressions are inherited by a typed variable from that typed variable's type definition, as illustrated by the following example. A typed variable's dimensions and element lengths are dependent on the current values of the extent expressions. /* TYPE DEFINITION */ DECLARE CHARX(N,N) CHAR( LENGTH(STRING) ) BASED, N FIXED BINARY(15), STRING CHAR(80) VARYING; /* TYPED VARIABLE */ DECLARE ARRAY TYPE(CHARX) BASED; The evaluation of extents when the array is referenced follows the same rules that apply to the evaluation of based
http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (164 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

variables. In the following example, the variable array is declared in a different block from CHARX: /*--------------------------------------------------*/ START: PROCEDURE; DECLARE CHARX(N,N) CHAR( LENGTH(STRING) ) BASED, N FIXED BINARY(15), STRING CHAR(80) VARYING; . . . /*--------------------------------------------------*/ NEXT: PROCEDURE; DECLARE ARRAY TYPE(CHARX) BASED, N FIXED BINARY(15), STRING CHAR(80) VARYING; . . . END NEXT; /*--------------------------------------------------*/ . . . END START; /*--------------------------------------------------*/ In the preceding example, Open PL/I uses the declarations in procedure NEXT to evaluate the extent expressions of ARRAY. Declarations in the current block are always used to evaluate extent expressions, even for variables that have not been declared with the TYPE attribute. (In the preceding example, if procedure NEXT did not declare N and STRING, those variable declarations in procedure START would be used.) If the REFER option is used in a type definition, the following are true:

If the type definition is a structure that has the BASED attribute with a REFER option, the BASED attribute for the corresponding typed variable must be specified. For example, in the following program fragment, VAR1 is a type definition, and VAR2 is a corresponding typed variable. The BASED attribute and a REFER option are specified in the declaration of VAR1. Therefore, the BASED attribute must be specified in the VAR2 declaration. DECLARE N FIXED BIN(15); /* TYPE DEFINITION: */ DECLARE 1 VAR1 BASED, 2 SIZE FIXED BIN(15), 2 ITEMS( N REFER(VAR1.SIZE) ) CHAR(80); DECLARE VAR2 TYPE(VAR1) BASED; when expanded yields: DECLARE 1 VAR2 BASED, 2 SIZE FIXED BIN(15),

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (165 of 166) [16-03-2013 17:31:34]

Open PL/I Language Reference Manual

2 ITEMS (N REFER (VAR2.SIZE)) CHAR(80); A variable declared with a REFER extent cannot be used as a type definition. For example, in the previous program fragment, VAR1.ITEMS cannot b

http://documentation.microfocus.com/help/advanc...focenter.enterprisedeveloper.vs/BKPFPFPREF.html (166 of 166) [16-03-2013 17:31:34]

Das könnte Ihnen auch gefallen