Cobol Guidelines -- Version 1.0
07/02/97
1. Basic Principles
2. Program Sequencing and Identification
3. Readability
4. Remarks
5. Input-Output Section
6. Working Storage Section
7. Linkage Section
8. Sections and Paragraphs
9. Routines
10. File Handling
11. Field Size
12. If Statements and Decision Logic
13. Performs
14. GO TOs
15. Comments and Self-Documenting Code
16. Printing
All programs should follow the basic principles of structured and top-down programming.
Procedure Division logic should follow the basic principles of structured and top-down programming whenever possible. Common sense should always prevail.
Structured programming involves dividing the Procedure Division into its logical parts (routines) so that each routine can be programmed independently. Modularity enables complex programs to be divided into many simple sections, each a separate entity. A mainline routine provides the master control that ties all other routines together and coordinates their activity.
The advantages of Structured programming include:
New production programs should contain blanks in columns 73-80.
To improve readability, only one verb or major clause
should be used per line.
For example:
SELECT CUSTMAST ASSIGN TO CUSTMAST ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS CUSTOMER-NUMBER
The remarks section should include a statement of purpose for the program, program synopsis and a modification history. The synopsis should describe the program's general processing flow, dependencies, purpose of each file, and other noteworthy considerations. Called routines should be listed.
The history should include the initials of the programmer who modified the program, the date, the ENDEVOR change control ID (CCID), and an explanation of the modification.
The remarks should use the following format:
*REMARKS. *********************************** * This program produces the daily New Order Transaction Report in customer number sequence. * The VSAM order transaction file is read and matched against the database customer master. The new order transaction report is written for each order which is for an existing customer. When no match for customer number is found, the customer number and name are written to the NEWCUST file for examination by the Sales Service department. The New Order report is currently reviewed by both the Sales Service department and the Order Entry supervisor. * Called sub-routines: * MASTERIO * ORDERPRT *********************************** * CHANGE LOG: * MRxxxx JS 01/01/91 Changed report column heading from MRXXXX 'CUST #' to 'CUST NUM'. * SRxxxx MJ 01/02/91 Added Customer address to report SRXXXX. * Changed report sequence from order number to customer number sequence. ***********************************
All SELECT verbs should begin in column 12.
All ASSIGN clauses should line up.
Object of ASSIGN should have external DDNAME only.
For example:
SELECT CUST-MAST ASSIGN TO CUSTMAST.Not:
SELECT CUST-MAST ASSIGN TO DA-D-CUSTMAST.
Names of data items which are members of a COPY should
be prefixed such that they are unique to that COPY definition. Data name
qualification is not recommended.
For example:
MST-STUDENT-NUMBERNot:
STUDENT-NUMBER OF MASTER-RECORDAll data-names should be meaningful.
GROSS-PAY, JOB-CLASS, FEDERAL-TAXNot:
GRPY, JC, FDTXUse a blank line or asterisk (*) between 01 levels.
Within an 01 level:
05 FILLER PIC X(28) VALUE 'THIS IS A LONG LITERAL FIELD'01 level entries should be formatted with the level number starting in column 8 and data names starting in column 12. Indent for each subsequent level number.
01 INPUT-RECORD. 03 MST-CONTROL-FIELD. 05 MST-MAJOR-CONTROL PIC XX. 05 MST-INITIAL-CONTROL PIC XXX. 05 MST-MINIMUM-CONTROL PIC XXX. 03 MST-DATA. 05 MST-NAME PIC X(25). 05 MST-AMOUNT PIC 999V99.If COMP fields are used, they should be synchronized for boundary alignment on a half, full, or double word, so that the compiler does not have to generate additional instructions.
01 NUMERIC-DATA. 03 CHAR-DATA PIC XX. 03 BINARY-DATA PIC S9(4) COMP.Define variable subscripts in binary format (COMP). All subscripts are converted to binary during resolution since subscripts are used as address displacements and addressing is done in binary
Use of 88 level condition elements is recommended, especially
for items with more than 2 values. Documentation is aided by meaningful
names associated with particular values, and maintenance is easier because
values can be changed without modification to the Procedure Division.
For example:
05 CODE-REC-TYPE PIC X(1). 88 CODE-REC-TYPE-ADD VALUE 'A'. 88 CODE-REC-TYPE-CHANGE VALUE 'C'. 88 CODE-REC-TYPE-DELETE VALUE 'D'.Work and message fields should be grouped into logical structures. The group name does not have to conform to naming standards since it serves as only a grouping, not a real element.
01 WORK-FIELDS 03 CNT-REC-IN PIC S9(3) COMP-3. 03 CNT-REC-OUT PIC S9(3) COMP-3. 03 CNT-PO-MAX PIC S9(5) COMP-3. 03 CNT-INVOICE-MAX PIC S9(5) COMP-3. 03 CNT-TRANS-GOOD PIC S9(5) COMP-3. 03 CNT-TRANS-BAD PIC S9(5) COMP-3. 01 MESSAGES 03 MSG-ERR-DATE PIC X(34) VALUE '---> ERROR, INVALID DATE ON ORDER'. 03 MSG-ERR-ACCTNUM PIC X(35) VALUE '---> ERROR, INVALID ACCOUNT NUMBER'.The maximum number of occurrences for a table should be specified in the value clause. This value can then be used for checking maximum table size.
01 TBL-TAX. 03 CNT-TAX-TBL-MAX PIC S9 (3) VALUE 35 COMP-3. 03 TBL-TAX-GROUP PIC X (3) OCCURS 35 TIMES INDEXED BY IND-TAX-GROUP.A REDEFINES storage description should be the same length as the item being redefined.
In the 'CALL' statement, code only one linkage parameter per line.
Section/paragraph names should clearly express the purpose of the module. Names should be prefixed with a 4 digit number. (SEE EXAMPLE BELOW *)
All sections should begin with a paragraph name.
When using sections, perform sections instead of paragraphs.
All section/paragraphs should be performed through the Section/paragraph exit.
A section/paragraph can have only one entry point and one exit.
Each section should have an exit paragraph suffixed EXIT
which contains the EXIT statement:
For example:
3500 EXIT.A section/paragraph should be exited only when all the statements have been executed and the EXIT statement is encountered or when there is a GO TO EXIT statement.
Use a blank (or comment) line to separate section/paragraph names. Within paragraphs, use a blank line to separate identifiable sub-functions.
It is recommended that the paragraph numbering scheme convey the relationships that exist between the paragraphs in a program. For example, the main control module could be numbered and named 000-MAIN. Modules are then numbered as follows:
0000-MAIN.
1000-HOUSEKEEPING
2000-PROCESSING
3000-MORE-PROCESSING
.
.
8000-END-OF-JOB
STOP RUN.
Other subordinate paragraphs could use the following pattern:
1000-HOUSEKEEPING performs
1100- that performs
1110- which then performs
1111-
.
.
.
.
1000-EXIT.
EXIT.
Level 1 modules increment the first digit of the paragraph number. Level 2 modules increment the second digit of the paragraph number. Level 3 modules increment the third digit of the paragraph number. Level 4 modules increment the fourth digit of the paragraph number. Unless a large complex program is being developed , it is seldom necessary to use more than 4 levels. Common routines such as print routines should be numbered in the 9000's.
This is a suggested pattern. Other numbering alternatives exist. Whatever method is chosen, it should allow one to easily follow the flow of a program.
All programs should have a MAIN ROUTINE. It should be level 0 and control all other major routines. All programs should have an INITIALIZATION routine. This routine is the first module performed in the MAIN ROUTINE. It is used to prepare the program by performing one-time processing functions such as:
Files should use the READ...INTO and WRITE...FROM options.
Each file should have only one READ statement.
If necessary, each file can have more than one WRITE statement, so that the WRITE...FROM option can be used. For files that are always written FROM the same Working-Storage layout, use only one write routine.
OPEN and CLOSE Statements.
Qualify each file as INPUT, OUTPUT, or I-O when it is OPENed.
OPEN only those files which are needed for that part of the program, instead of opening all files at the beginning and closing all files at the end.
The first files OPENed should contain the control input or parameter cards. These records should be successfully edited before any other files are OPENed.
When issuing MOVEs, sending and receiving fields should
be the appropriate length.
For example:
01 A PIC X(4)Good:
MOVE 'ABC ' TO A.Not:
MOVE 'ABC' TO A.
A decision structure should be coded as close to a natural English question as possible.
Avoid using negative conditions, especially in compound
conditions. Never use double negatives. Negative relational operators are
acceptable if needed, but subject relational operators are unacceptable.
For example:
IF A NOT LESS THAN B...Not:
IF NOT A LESS THAN B...When using nested IF statements, keep the logic simple Avoid using more than 3 levels of nesting. When deeper nesting is required, procedures or performs may be used.
Nested IF statements should be indented and ELSE clauses aligned under the corresponding IF. The imperative statements for the IF and the imperative statements for the ELSE should also be aligned and indented. To avoid erroneous and unmatched conditions, an ELSE clause should be coded for each IF, even when NEXT SENTENCE is required.
Case structures should be coded as a chain of IF statements (instead of a GO TO...DEPENDING ON).
Newer versions of COBOL may provide alternative solutions to nesting/case structures that would be equally acceptable.
Use PERFORM...VARYING...UNTIL to control iterations of logic. Do not use manually incremented counters when a VARYING clause can be used.
The use of the VARYING option of the PERFORM verb is encouraged, as this type of PERFORM is self-documenting. Avoid multi-level VARYING clauses. For readability, visually separate the PERFORM options:
PERFORM 9010-WRITE-FINDER-FILE THRU 9010-EXIT
VARYING FINDER-INDEX FROM 1 BY 1
UNTIL FINDER-INDEX GREATER THAN FINDER-COUNT.
GO TO statements should only be used to branch down to the exit of a section/paragraph or to an abort routine.
Self documenting code relies on good programming style to carry the greater part of the documentation burden. The program should contain as many comment statements as necessary to fully document it:
When printing lines, BEFORE or AFTER ADVANCING commands may be used. DO NOT mix these commands within a program.
Examine line counts BEFORE a line is printed to determine whether a page eject and/or heading line is needed.
Return to: Systems
Development Home Page
Return to: UMS Home Page
This page was last updated on September 2, 2004
Comments to: Quality Coordinator