24 min read

> "The structure of a COBOL program is not merely organizational convenience -- it is the language's philosophy made manifest. Every division, every section, every paragraph exists because the creators of COBOL believed that programs should be as...

Chapter 2: COBOL Program Structure -- Divisions, Sections, and Paragraphs

"The structure of a COBOL program is not merely organizational convenience -- it is the language's philosophy made manifest. Every division, every section, every paragraph exists because the creators of COBOL believed that programs should be as readable and well-organized as business documents."


2.1 Introduction: The Architecture of a COBOL Program

If you were to design a programming language for business, how would you organize a program? The designers of COBOL answered this question in 1959 with an architectural decision that has endured for over six decades: the four-division structure.

Every COBOL program -- whether it is ten lines or ten thousand -- follows the same fundamental blueprint. This blueprint divides a program into four distinct sections, each with a clearly defined purpose:

  1. IDENTIFICATION DIVISION -- Who is this program?
  2. ENVIRONMENT DIVISION -- Where does it run?
  3. DATA DIVISION -- What data does it use?
  4. PROCEDURE DIVISION -- What does it do?

This structure is not optional. It is not a convention or a best practice. It is a language requirement. The divisions must appear in this exact order, and together they define every aspect of a COBOL program's identity, environment, data, and logic.

Before we explore each division in depth, let us first understand the physical layout of COBOL source code, because the structure of a COBOL program begins at the level of individual columns on a line.


2.2 The Reference Format: Columns and Areas

COBOL was born in an era when programs were written on 80-column punched cards. Each card held one line of code, and specific columns had specific meanings. This fixed reference format has survived into the modern era, and understanding it is essential for reading and writing COBOL.

2.2.1 The Six Areas of a COBOL Line

Every line in a fixed-format COBOL program is divided into six areas:

Area Columns Purpose
Sequence Number Area 1-6 Line numbering (ignored by compiler)
Indicator Area 7 Comment, continuation, or debug marker
Area A 8-11 Division headers, section headers, paragraph names, level indicators (01, 77, FD, SD)
Area B 12-72 Statements, clauses, sentences, continuation text
Identification Area 73-80 Program identification (ignored by compiler)

Here is a visual representation:

Column:  1234567890123456789012345678901234567890...7273747576777879 80
         |     ||    |                              |              |
         Seq#  |A    B ........(program text)....... Identification
              Ind  Area A starts here (col 8)        Area (ignored)

2.2.2 The Sequence Number Area (Columns 1-6)

In the punched-card era, these six columns held numeric sequence numbers so that if a deck of cards was dropped, they could be reassembled in the correct order. Modern compilers ignore these columns entirely, but they remain part of the format specification.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.    EXAMPLE.
000300 PROCEDURE DIVISION.
000400     DISPLAY "HELLO, WORLD"
000500     STOP RUN.

You may leave columns 1-6 blank (and most modern programmers do), or fill them with any characters. The compiler will not process them.

2.2.3 The Indicator Area (Column 7)

Column 7 is the indicator area -- a single column with significant power. The character placed here determines how the compiler treats the rest of the line:

Character Meaning
(space) Normal source line
* Comment line (entire line is ignored)
/ Comment line with page eject in listing
D or d Debugging line (compiled only when DEBUGGING MODE is active)
- Continuation of previous line

Comment Lines:

      * This entire line is a comment.
      * The compiler ignores everything on this line.
      / This is also a comment, but forces a new page in the listing.

Comments are your primary documentation tool in COBOL. Use them liberally to explain the purpose of sections, paragraphs, and complex logic.

Debugging Lines:

      D    DISPLAY "DEBUG: WS-COUNTER = " WS-COUNTER
      D    DISPLAY "DEBUG: ENTERING 2000-PROCESS"

Debugging lines are compiled only when WITH DEBUGGING MODE is specified in the SOURCE-COMPUTER paragraph. Without it, the compiler treats these lines as comments. This provides a built-in mechanism for conditional compilation of debug code.

Continuation Lines:

When a literal or word is too long to fit on a single line, you use a continuation line:

       01  WS-LONG-MESSAGE    PIC X(80) VALUE "THIS IS A VER
      -    "Y LONG STRING THAT CONTINUES ON THE NEXT LINE".

The rules for continuation are: 1. Place a hyphen (-) in column 7 of the continuation line 2. For non-literal continuation, the text continues in Area B (column 12 or later) 3. For literal continuation, close the quote on the first line at or before column 72, then on the continuation line place the hyphen in column 7 and reopen the quote before continuing the text

2.2.4 Area A (Columns 8-11) and Area B (Columns 12-72)

The distinction between Area A and Area B is one of the most important formatting rules in COBOL. Certain elements must begin in Area A, while others must begin in Area B.

Must begin in Area A (columns 8-11): - Division headers (IDENTIFICATION DIVISION.) - Section headers (WORKING-STORAGE SECTION.) - Paragraph names (0000-MAIN.) - Level indicators: FD, SD, 01, 77 - END PROGRAM header

Must begin in Area B (columns 12-72): - Statements and sentences (DISPLAY "HELLO", MOVE X TO Y) - Clauses and entries within a statement - Level numbers 02 through 49, 66, 88 - Continuation text

Here is a properly formatted example showing Area A and Area B usage:

       IDENTIFICATION DIVISION.                        <- Area A
       PROGRAM-ID.    AREADEMO.                        <- Area A
       DATA DIVISION.                                  <- Area A
       WORKING-STORAGE SECTION.                        <- Area A
       01  WS-NAME         PIC X(20).                  <- Area A (01)
           05  WS-FIRST    PIC X(10).                  <- Area B (05)
           05  WS-LAST     PIC X(10).                  <- Area B (05)
       77  WS-COUNT        PIC 9(5).                   <- Area A (77)
       PROCEDURE DIVISION.                             <- Area A
       0000-MAIN.                                      <- Area A
           DISPLAY "HELLO"                             <- Area B
           STOP RUN.                                   <- Area B

2.2.5 The Identification Area (Columns 73-80)

Columns 73-80 were historically used to identify the program or punch card deck. The compiler ignores these columns entirely. In practice, modern programmers rarely use them.


2.3 Fixed-Format vs. Free-Format COBOL

The column-based layout described above is called fixed reference format (or simply fixed format). It is the traditional format and remains dominant in production mainframe environments. However, COBOL-2002 introduced free reference format (free format), which removes column restrictions entirely.

2.3.1 Free-Format Rules

In free format: - Code can start in any column - There is no sequence number area, indicator area, or identification area - Lines can be up to 255 characters (compiler-dependent; some allow more) - There is no Area A / Area B distinction - Comments begin with *> and can appear anywhere on a line (including inline) - Debugging lines use >>D at the start of the line - Continuation uses ampersand (&) for literal concatenation instead of the column-7 hyphen

2.3.2 Side-by-Side Comparison

Fixed Format:

      * This is a comment
       IDENTIFICATION DIVISION.
       PROGRAM-ID.    EXAMPLE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-MSG          PIC X(50) VALUE
      -    "HELLO FROM FIXED FORMAT".
       PROCEDURE DIVISION.
       0000-MAIN.
      D    DISPLAY "DEBUG MODE ON"
           DISPLAY WS-MSG
           STOP RUN.

Free Format:

*> This is a comment
identification division.
program-id. Example.
data division.
working-storage section.
01 ws-msg pic x(50) value
    "HELLO FROM FREE FORMAT".
procedure division.
0000-main.
>>D display "DEBUG MODE ON"
    display ws-msg
    stop run.

2.3.3 Enabling Free Format

The method for enabling free format depends on your compiler:

Compiler Method
GnuCOBOL -free command-line flag, or >>SOURCE FORMAT IS FREE directive
Micro Focus $SET SOURCEFORMAT"FREE" directive
IBM Enterprise COBOL PROCESS FREE or CBL FREE statement
Fujitsu NetCOBOL Compiler option setting

2.3.4 Which Format Should You Use?

For new projects, free format offers clear advantages: more readable code, longer lines, inline comments, and a more familiar feel for programmers coming from other languages. However, the vast majority of existing COBOL code -- billions of lines -- is in fixed format. If you will be maintaining legacy systems, you must be fluent in fixed format. This book uses fixed format as the primary format with free-format equivalents shown for comparison, because fixed format remains the industry standard for production COBOL.


2.4 The IDENTIFICATION DIVISION

The IDENTIFICATION DIVISION is the only required division in a COBOL program. Its primary purpose is to name the program and provide documentation metadata.

2.4.1 Syntax

       IDENTIFICATION DIVISION.
       PROGRAM-ID.    program-name [IS INITIAL | COMMON | RECURSIVE].
       AUTHOR.        author-name.
       INSTALLATION.  installation-description.
       DATE-WRITTEN.  date-text.
       DATE-COMPILED. date-text.
       SECURITY.      security-description.

In COBOL-2002 and later, you can abbreviate the header:

       ID DIVISION.
       PROGRAM-ID. program-name.

2.4.2 PROGRAM-ID: The Only Required Paragraph

The PROGRAM-ID paragraph assigns a name to the program. This name is used by the operating system, the linker, and by other programs that CALL this program.

Rules for program names: - 1 to 30 characters (8 in older standards) - Must begin with a letter - Can contain letters, digits, and hyphens - Cannot end with a hyphen - Cannot be a COBOL reserved word - Case sensitivity depends on the compiler

       PROGRAM-ID.    PAYROLL-PROCESS.

Optional clauses for PROGRAM-ID:

Clause Purpose
IS INITIAL Program is returned to its initial state each time it is called
IS COMMON Program can be called by sibling programs in a nested structure
IS RECURSIVE Program can call itself (COBOL-2002+)
       PROGRAM-ID.    CALCULATE-TAX IS INITIAL.

The IS INITIAL clause is particularly important for subprograms. Without it, WORKING-STORAGE variables retain their values between calls. With it, all variables are re-initialized to their VALUE clauses each time the program is called.

2.4.3 Optional Paragraphs

All other paragraphs in the IDENTIFICATION DIVISION are optional. In COBOL-2002 and later, they are classified as obsolete but remain supported by virtually all compilers. They serve a purely documentary purpose -- the compiler does not validate or enforce their content (with the exception of DATE-COMPILED, which some compilers replace with the actual compilation date).

Paragraph Purpose Typical Content
AUTHOR Who wrote the program Developer name, team name
INSTALLATION Where the program runs Data center, server name, department
DATE-WRITTEN When the program was created Date in any text format
DATE-COMPILED When the program was last compiled Automatically filled by some compilers
SECURITY Access or classification notes Confidentiality level, restrictions

Example with all paragraphs:

       IDENTIFICATION DIVISION.
       PROGRAM-ID.    ACCT-RECV.
       AUTHOR.        MARY CHEN, ACCOUNTS TEAM.
       INSTALLATION.  CHICAGO DATA CENTER - SERVER FARM 3.
       DATE-WRITTEN.  2026-01-15.
       DATE-COMPILED.
       SECURITY.      CONFIDENTIAL - SOX COMPLIANCE REQUIRED.

2.4.4 Best Practices

While the optional paragraphs are obsolete in the standard, many organizations still require them as part of their coding standards. The rationale is straightforward: in a production environment with thousands of COBOL programs, this built-in metadata is invaluable for maintenance. When you open a 5,000-line program at 2 AM during an outage, knowing who wrote it and when can save precious time.

If your shop uses version control (and it should), much of this information is available through the version control system. In that case, a prominent comment block may serve the same purpose:

      *================================================================*
      * Program:     ACCT-RECV
      * Description: Accounts receivable batch processing
      * Author:      Mary Chen (mary.chen@acme.com)
      * Created:     2026-01-15
      * Modified:    2026-02-10 - Added aging report (J. Smith)
      * Repository:  git://mainframe/accounting/acct-recv.git
      *================================================================*
       IDENTIFICATION DIVISION.
       PROGRAM-ID.    ACCT-RECV.

2.5 The ENVIRONMENT DIVISION

The ENVIRONMENT DIVISION describes the computing environment in which the program will be compiled and executed. It is the most platform-dependent part of a COBOL program. When porting a program from one system to another, the ENVIRONMENT DIVISION typically requires the most changes.

The ENVIRONMENT DIVISION contains two sections: 1. CONFIGURATION SECTION -- Computer and special-name definitions 2. INPUT-OUTPUT SECTION -- File assignments and I/O control

Both sections and the division itself are optional. A minimal program may omit the ENVIRONMENT DIVISION entirely.

2.5.1 CONFIGURATION SECTION

The CONFIGURATION SECTION contains up to three paragraphs.

SOURCE-COMPUTER

Identifies the computer where the program will be compiled.

       SOURCE-COMPUTER. IBM-MAINFRAME WITH DEBUGGING MODE.

The computer name is treated as a comment. The key clause here is WITH DEBUGGING MODE, which activates debugging lines (those with D in column 7).

OBJECT-COMPUTER

Identifies the computer where the compiled program will run.

       OBJECT-COMPUTER. IBM-MAINFRAME
           PROGRAM COLLATING SEQUENCE IS SPECIAL-SEQUENCE.

The most useful clause is PROGRAM COLLATING SEQUENCE, which specifies the character ordering used for comparisons and sorting. This is important for international applications where the default (EBCDIC or ASCII) ordering may not match local conventions.

SPECIAL-NAMES

The SPECIAL-NAMES paragraph is the most powerful paragraph in the CONFIGURATION SECTION. It allows you to customize the program's behavior in several ways:

Decimal point notation:

       SPECIAL-NAMES.
           DECIMAL-POINT IS COMMA.

This causes COBOL to swap the roles of the period and comma in numeric formatting. The number 1,234.56 would be displayed as 1.234,56 -- the European convention. This is purely a source-code and display convention; it does not affect internal storage.

Currency sign:

       SPECIAL-NAMES.
           CURRENCY SIGN IS "EUR" WITH PICTURE SYMBOL "E".

This allows you to use a custom currency symbol in PICTURE clauses. With the definition above, PIC EEE,EE9.99 would format values with the EUR prefix.

Class conditions:

       SPECIAL-NAMES.
           CLASS VALID-LETTER IS "A" THRU "Z" "a" THRU "z"
           CLASS VALID-DIGIT  IS "0" THRU "9".

Class conditions create custom data validation tests. After defining these, you can write:

           IF WS-INPUT IS VALID-LETTER
               DISPLAY "INPUT IS ALPHABETIC"
           END-IF

Mnemonic names:

       SPECIAL-NAMES.
           CONSOLE IS OPERATOR-TERMINAL
           PRINTER IS LINE-PRINTER.

Mnemonic names map implementor-defined device names to user-defined names, providing an abstraction layer.

Symbolic characters:

       SPECIAL-NAMES.
           SYMBOLIC CHARACTERS TAB-CHAR IS 10
                               LF-CHAR  IS 11.

This assigns user-defined names to specific characters in the character set by their ordinal position (the actual position depends on whether the system uses ASCII or EBCDIC).

2.5.2 INPUT-OUTPUT SECTION

The INPUT-OUTPUT SECTION maps logical file names used in the program to physical files on the system. It contains two paragraphs.

FILE-CONTROL

The FILE-CONTROL paragraph contains a SELECT statement for each file the program uses. This is where COBOL achieves its powerful file-handling abstraction: the program logic works with logical file names, and the physical file assignments can be changed without modifying the PROCEDURE DIVISION.

       FILE-CONTROL.
           SELECT logical-file-name
               ASSIGN TO physical-file-name
               ORGANIZATION IS organization-type
               ACCESS MODE IS access-mode
               RECORD KEY IS key-field
               FILE STATUS IS status-field.

File organizations:

Organization Description Use Case
SEQUENTIAL Records accessed in order Batch processing, tape files
LINE SEQUENTIAL Text files with line delimiters Reports, CSV files
RELATIVE Records accessed by record number Direct access by position
INDEXED Records accessed by key value Master files, databases

Access modes:

Mode Description
SEQUENTIAL Records read/written in order
RANDOM Records read/written by key or record number
DYNAMIC Both sequential and random access

Here is a comprehensive example:

       FILE-CONTROL.
      *    Sequential text file
           SELECT EMPLOYEE-FILE
               ASSIGN TO "EMPFILE.DAT"
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-EMP-STATUS.

      *    Indexed file with primary and alternate keys
           SELECT CUSTOMER-FILE
               ASSIGN TO "CUSTMAST.DAT"
               ORGANIZATION IS INDEXED
               ACCESS MODE IS DYNAMIC
               RECORD KEY IS CUST-ID
               ALTERNATE RECORD KEY IS CUST-NAME
                   WITH DUPLICATES
               FILE STATUS IS WS-CUST-STATUS.

      *    Relative file
           SELECT TRANSACTION-LOG
               ASSIGN TO "TRANSLOG.DAT"
               ORGANIZATION IS RELATIVE
               ACCESS MODE IS RANDOM
               RELATIVE KEY IS WS-RELATIVE-KEY
               FILE STATUS IS WS-TRANS-STATUS.

The FILE STATUS clause is a critical best practice. It directs the system to store a two-character status code after each file operation, allowing your program to detect and handle errors gracefully. Common status codes include:

Status Meaning
00 Successful completion
10 End of file reached
22 Duplicate key (indexed file)
23 Record not found
30 Permanent I/O error
35 File not found
41 File already open

Always check the file status after every file operation. This is one of the most important defensive programming practices in COBOL.

I-O-CONTROL

The I-O-CONTROL paragraph specifies special I/O techniques. It is less commonly used in modern programs but can be important for batch processing:

       I-O-CONTROL.
           SAME RECORD AREA FOR FILE-A FILE-B.

The SAME RECORD AREA clause tells the compiler that two files share the same record buffer, which can save memory in resource-constrained environments. The RERUN clause (for checkpoint/restart) and the MULTIPLE FILE TAPE clause are other options, though they are rarely used in modern development.


2.6 The DATA DIVISION

The DATA DIVISION defines every piece of data the program will use. In a typical COBOL program, the DATA DIVISION is often the largest division, sometimes accounting for more than half the total lines of code. This may surprise programmers from other languages, but it reflects COBOL's philosophy: data structures should be explicitly and completely defined, not inferred by the compiler.

2.6.1 FILE SECTION

The FILE SECTION defines the record layout for each file declared in the FILE-CONTROL paragraph. Each file requires an FD (File Description) entry followed by one or more record descriptions.

       FILE SECTION.
       FD  EMPLOYEE-FILE
           LABEL RECORDS ARE STANDARD
           RECORD CONTAINS 80 CHARACTERS
           BLOCK CONTAINS 10 RECORDS
           DATA RECORD IS EMPLOYEE-RECORD.
       01  EMPLOYEE-RECORD.
           05  EMP-ID              PIC 9(6).
           05  EMP-NAME            PIC X(30).
           05  EMP-DEPARTMENT      PIC X(20).
           05  EMP-SALARY          PIC 9(7)V99.
           05  FILLER              PIC X(15).

Key points about the FILE SECTION:

  • FD must begin in Area A
  • The 01 level record description defines the layout of each record
  • Multiple 01 level entries under the same FD share the same physical buffer (they provide different views of the same storage)
  • FILLER is used for unused portions of the record
  • For sort files, use SD (Sort Description) instead of FD

2.6.2 WORKING-STORAGE SECTION

The WORKING-STORAGE SECTION defines variables that persist for the entire life of the program. Values set with VALUE clauses are initialized once when the program is first loaded. These values are retained across PERFORM calls and, importantly, across multiple calls to the program from a calling program (unless IS INITIAL is specified in the PROGRAM-ID).

       WORKING-STORAGE SECTION.

      * Independent elementary items (77-level)
       77  WS-RETURN-CODE      PIC S9(4)   VALUE ZERO.

      * Group items with subordinate fields
       01  WS-FLAGS.
           05  WS-EOF-FLAG     PIC X       VALUE 'N'.
               88  END-OF-FILE VALUE 'Y'.
               88  NOT-EOF     VALUE 'N'.

      * Counters
       01  WS-COUNTERS.
           05  WS-RECORD-COUNT PIC 9(7)    VALUE ZEROS.
           05  WS-ERROR-COUNT  PIC 9(5)    VALUE ZEROS.

Level numbers and their meanings:

Level Purpose
01 Record level (group item or independent elementary item)
02-49 Subordinate items within a group
66 RENAMES (alternative grouping of items)
77 Independent elementary item (not part of any group)
88 Condition name (used for boolean-like tests)

Level 88: Condition Names

Condition names are one of COBOL's most elegant features. They associate meaningful names with specific values:

       01  WS-ACCOUNT-TYPE     PIC X.
           88  CHECKING        VALUE 'C'.
           88  SAVINGS         VALUE 'S'.
           88  MONEY-MARKET    VALUE 'M'.
           88  INVALID-TYPE    VALUE 'X' THRU 'Z'.

You can then write readable conditions:

           IF CHECKING
               PERFORM PROCESS-CHECKING
           END-IF

           SET SAVINGS TO TRUE

REDEFINES: Alternative Views of the Same Storage

       01  WS-DATE-NUMERIC     PIC 9(8).
       01  WS-DATE-PARTS REDEFINES WS-DATE-NUMERIC.
           05  WS-YEAR         PIC 9(4).
           05  WS-MONTH        PIC 9(2).
           05  WS-DAY          PIC 9(2).

Both WS-DATE-NUMERIC and WS-DATE-PARTS occupy the same storage. Moving 20260210 to WS-DATE-NUMERIC makes WS-YEAR equal to 2026, WS-MONTH equal to 02, and WS-DAY equal to 10.

OCCURS: Tables and Arrays

       01  WS-MONTHLY-TOTALS.
           05  WS-MONTH-TOTAL  PIC 9(9)V99
               OCCURS 12 TIMES.

This creates an array of 12 numeric items, accessed as WS-MONTH-TOTAL(1) through WS-MONTH-TOTAL(12).

2.6.3 LOCAL-STORAGE SECTION

Introduced in COBOL-2002, LOCAL-STORAGE is similar to WORKING-STORAGE with one critical difference: LOCAL-STORAGE items are re-initialized to their VALUE clauses each time the program is invoked via a CALL statement.

       WORKING-STORAGE SECTION.
       01  WS-CALL-COUNT       PIC 9(3)  VALUE ZEROS.

       LOCAL-STORAGE SECTION.
       01  LS-TEMP-RESULT      PIC 9(9)V99  VALUE ZEROS.

If this program is called three times, WS-CALL-COUNT retains its accumulated value (1, 2, 3), while LS-TEMP-RESULT is reset to zero at the start of each call. This distinction is crucial for writing reliable subprograms.

2.6.4 LINKAGE SECTION

The LINKAGE SECTION defines data items that are passed to the program by a calling program via the CALL ... USING statement. Items in the LINKAGE SECTION do not occupy storage in the called program; they describe the layout of data whose storage is owned by the calling program.

       LINKAGE SECTION.
       01  LS-EMPLOYEE-ID      PIC 9(6).
       01  LS-ACTION-CODE      PIC X.
       01  LS-RETURN-CODE      PIC S9(4).

       PROCEDURE DIVISION USING LS-EMPLOYEE-ID
                                LS-ACTION-CODE
                                LS-RETURN-CODE.

Important rules: - VALUE clauses are not allowed in the LINKAGE SECTION (except for 88-level items) - The USING clause in the PROCEDURE DIVISION header maps parameters in order - The number and sizes of parameters must match between the calling and called programs

2.6.5 Other Sections

COBOL defines several additional DATA DIVISION sections for specialized purposes:

REPORT SECTION: Used with the Report Writer feature to define complex report layouts declaratively. The Report Writer automates page breaks, headers, footers, and control breaks. While powerful, it is not supported by all compilers.

       REPORT SECTION.
       RD  SALES-REPORT
           CONTROL IS FINAL REGION-CODE
           PAGE LIMIT IS 60 LINES
           HEADING 1
           FIRST DETAIL 5
           LAST DETAIL 55
           FOOTING 58.

SCREEN SECTION: Used for interactive terminal programs to define screen layouts with field positioning, colors, and input/output attributes.

       SCREEN SECTION.
       01  MAIN-SCREEN.
           05  BLANK SCREEN.
           05  LINE 1 COLUMN 30 VALUE "EMPLOYEE INQUIRY"
               HIGHLIGHT.
           05  LINE 3 COLUMN 5 VALUE "EMPLOYEE ID: ".
           05  LINE 3 COLUMN 18 PIC 9(6)
               USING WS-EMPLOYEE-ID
               HIGHLIGHT AUTO.

2.7 The PROCEDURE DIVISION

The PROCEDURE DIVISION contains the executable logic of the program -- this is where the program actually does something. While the other three divisions are declarative (they describe things), the PROCEDURE DIVISION is imperative (it commands actions).

2.7.1 Hierarchical Structure

The PROCEDURE DIVISION has a four-level hierarchy:

PROCEDURE DIVISION
    |
    +-- SECTION (optional grouping)
    |       |
    |       +-- PARAGRAPH (named block of code)
    |               |
    |               +-- SENTENCE (one or more statements, ending with a period)
    |                       |
    |                       +-- STATEMENT (a single COBOL verb and its operands)

Statements

A statement is a single COBOL verb and its operands. It is the smallest unit of executable code:

           MOVE 42 TO WS-RESULT
           DISPLAY "HELLO, WORLD"
           ADD 1 TO WS-COUNTER
           READ EMPLOYEE-FILE AT END SET END-OF-FILE TO TRUE END-READ

Sentences

A sentence is one or more statements terminated by a period. The period is significant in COBOL -- it acts as a scope terminator for the entire sentence:

      * One statement, one sentence:
           DISPLAY "HELLO".

      * Multiple statements in one sentence:
           MOVE 0 TO WS-COUNTER
           MOVE SPACES TO WS-NAME
           MOVE "N" TO WS-EOF-FLAG.

Paragraphs

A paragraph is a named block of code consisting of one or more sentences. The paragraph name must begin in Area A and is followed by a period:

       1000-INITIALIZE.
           OPEN INPUT EMPLOYEE-FILE
           OPEN OUTPUT REPORT-FILE
           SET NOT-END-OF-FILE TO TRUE
           PERFORM 8000-READ-EMPLOYEE
           .

Paragraphs are the basic units of program organization in the PROCEDURE DIVISION. They can be PERFORMed (called) from other paragraphs:

           PERFORM 1000-INITIALIZE

Sections

A section is a named group of one or more paragraphs. The section name must begin in Area A and is followed by the word SECTION and a period:

       1000-INITIALIZATION SECTION.

       1000-INIT-START.
           OPEN INPUT EMPLOYEE-FILE
           .

       1100-OPEN-REPORT.
           OPEN OUTPUT REPORT-FILE
           .

       1000-INIT-EXIT.
           EXIT.

When you PERFORM a section, COBOL executes all paragraphs within that section from beginning to end. Sections provide a higher level of organization and are particularly useful in large programs.

2.7.2 Sections vs. Paragraphs: When to Use Which

This is a perennial debate in the COBOL community. Here are the two main approaches:

Paragraphs Only (no sections):

       PROCEDURE DIVISION.
       0000-MAIN.
           PERFORM 1000-INITIALIZE
           PERFORM 2000-PROCESS UNTIL END-OF-FILE
           PERFORM 3000-FINALIZE
           STOP RUN.

       1000-INITIALIZE.
           OPEN INPUT EMP-FILE
           PERFORM 8000-READ-EMPLOYEE.

       2000-PROCESS.
           ADD 1 TO WS-COUNT
           PERFORM 8000-READ-EMPLOYEE.

       3000-FINALIZE.
           CLOSE EMP-FILE
           DISPLAY "DONE: " WS-COUNT " RECORDS".

       8000-READ-EMPLOYEE.
           READ EMP-FILE AT END SET END-OF-FILE TO TRUE END-READ.

Sections with Paragraphs:

       PROCEDURE DIVISION.
       0000-MAIN-CONTROL SECTION.
       0000-MAIN.
           PERFORM 1000-INITIALIZATION
           PERFORM 2000-PROCESS UNTIL END-OF-FILE
           PERFORM 3000-FINALIZATION
           STOP RUN.
       0000-MAIN-EXIT.
           EXIT.

       1000-INITIALIZATION SECTION.
       1000-INIT-START.
           OPEN INPUT EMP-FILE
           PERFORM 8000-READ-EMPLOYEE.
       1000-INIT-EXIT.
           EXIT.

Each approach has advocates. Sections provide better organization in large programs and interact differently with the PERFORM THRU statement. Paragraphs are simpler and sufficient for smaller programs. Many mainframe shops have coding standards that mandate one style or the other.

2.7.3 Naming Conventions

There is no universal standard for paragraph and section naming, but the most widely adopted convention uses a numeric prefix to indicate the logical grouping:

Range Purpose
0000-0999 Main control / top-level logic
1000-1999 Initialization
2000-2999 Main processing
3000-3999 Output / report generation
4000-4999 Finalization / cleanup
5000-7999 Application-specific processing
8000-8999 Utility / common routines
9000-9999 Error handling

Combined with descriptive names:

       0000-MAIN-CONTROL.
       1000-INITIALIZE.
       2000-PROCESS-TRANSACTIONS.
       2100-VALIDATE-TRANSACTION.
       2200-APPLY-TRANSACTION.
       3000-PRINT-REPORT.
       3100-PRINT-HEADERS.
       3200-PRINT-DETAIL.
       3300-PRINT-TOTALS.
       4000-FINALIZE.
       8000-READ-TRANSACTION.
       8100-READ-MASTER.
       9000-HANDLE-FILE-ERROR.
       9100-HANDLE-DATA-ERROR.

This convention has two enormous benefits: 1. Reading the code, you can instantly identify what category of processing a paragraph performs just by its number. 2. Searching the listing, paragraphs naturally sort into logical groups.

2.7.4 The PROCEDURE DIVISION USING Clause

When a program receives parameters from a calling program, the USING clause on the PROCEDURE DIVISION header connects the LINKAGE SECTION items to the incoming parameters:

       PROCEDURE DIVISION USING LS-EMPLOYEE-ID
                                LS-ACTION-CODE
                                LS-RETURN-CODE.

The parameters are matched by position, not by name. The first item in the CALL matches the first item in the USING, and so on.


2.8 The Period: Statement Terminator and Scope Delimiter

The period (.) in COBOL is one of the most consequential punctuation marks in any programming language. It terminates sentences and implicitly closes all open scope delimiters. This dual role has been the source of countless bugs.

2.8.1 The Problem with Periods

Consider this code:

           IF WS-BALANCE > 0
               DISPLAY "POSITIVE BALANCE"
               PERFORM 2000-PROCESS-CREDIT.
               DISPLAY "CREDIT PROCESSED".

The period after PERFORM 2000-PROCESS-CREDIT terminates the IF statement. The second DISPLAY executes unconditionally, regardless of whether WS-BALANCE > 0. This is a classic and insidious bug because the indentation suggests both statements are inside the IF, but the period says otherwise.

2.8.2 Scope Terminators: The Modern Solution

COBOL-85 introduced explicit scope terminators to solve this problem. These are END- keywords that explicitly close a statement:

           IF WS-BALANCE > 0
               DISPLAY "POSITIVE BALANCE"
               PERFORM 2000-PROCESS-CREDIT
               DISPLAY "CREDIT PROCESSED"
           END-IF

Now the intent is unambiguous. The END-IF explicitly terminates the IF statement, and all three subordinate statements are clearly inside the IF block.

Common scope terminators include:

Scope Terminator Closes
END-IF IF statement
END-EVALUATE EVALUATE statement
END-PERFORM Inline PERFORM
END-READ READ statement
END-WRITE WRITE statement
END-COMPUTE COMPUTE statement
END-STRING STRING statement
END-UNSTRING UNSTRING statement
END-SEARCH SEARCH statement
END-CALL CALL statement
END-ADD ADD statement
END-SUBTRACT SUBTRACT statement
END-MULTIPLY MULTIPLY statement
END-DIVIDE DIVIDE statement

2.8.3 Best Practice: Minimize Periods

The modern best practice is to use exactly one period per paragraph -- at the very end of the paragraph. Use explicit scope terminators for all conditional and I/O statements within the paragraph.

       2000-PROCESS-RECORD.
           IF WS-RECORD-TYPE = "A"
               PERFORM 2100-PROCESS-TYPE-A
           ELSE
               IF WS-RECORD-TYPE = "B"
                   PERFORM 2200-PROCESS-TYPE-B
               ELSE
                   PERFORM 9000-HANDLE-ERROR
               END-IF
           END-IF
           ADD 1 TO WS-RECORD-COUNT
           .

Note the lone period on its own line at the end of the paragraph. This style makes the paragraph boundary visible and eliminates the risk of accidental scope termination.


2.9 Naming Rules for User-Defined Words

COBOL has specific rules for the names you create for data items, paragraphs, sections, and files.

2.9.1 General Rules

  1. Length: 1 to 30 characters
  2. Characters allowed: Letters (A-Z, a-z), digits (0-9), and hyphens (-)
  3. Must contain at least one letter (except paragraph names, which can be all digits)
  4. Cannot begin or end with a hyphen
  5. Cannot be a COBOL reserved word
  6. Not case-sensitive (in most compilers): WS-COUNT, ws-count, and Ws-Count are the same name

2.9.2 Data Name Prefixing Convention

A widely adopted convention is to prefix data names based on their section:

Prefix Section / Usage
WS- WORKING-STORAGE SECTION
LS- LOCAL-STORAGE SECTION or LINKAGE SECTION
EMP- Fields in EMPLOYEE record
CUST- Fields in CUSTOMER record
WS-DET- Detail line fields
WS-HDR- Header line fields
WS-TOT- Total/summary fields

This convention is not enforced by the compiler, but it dramatically improves readability. When you see WS-RECORD-COUNT in the PROCEDURE DIVISION, you immediately know it is defined in WORKING-STORAGE. When you see EMP-SALARY, you know it is part of the employee record.

2.9.3 Reserved Words

COBOL has a large set of reserved words -- over 400 in some standards. You cannot use any reserved word as a data name, paragraph name, or section name. Common pitfalls include:

  • DATE is reserved -- use WS-DATE instead
  • TIME is reserved -- use WS-TIME instead
  • COUNT is reserved in some compilers -- use WS-COUNT
  • STATUS is reserved -- use WS-STATUS
  • LENGTH is reserved in COBOL-2002+ -- use WS-LENGTH

When in doubt, prefix your names. The WS- convention virtually eliminates reserved word conflicts.


2.10 COBOL Program Compilation and Execution Flow

Understanding how a COBOL program goes from source code to running program helps clarify why the division structure matters.

2.10.1 The Compilation Process

Source Code (.cob/.cbl)
        |
        v
   [COMPILER]  <-- Uses ENVIRONMENT DIVISION for configuration
        |
        v
Object Module (.o/.obj)
        |
        v
   [LINKER]    <-- Resolves CALL references, links libraries
        |
        v
Executable Program (.exe/load module)
        |
        v
   [RUNTIME]   <-- Uses ENVIRONMENT DIVISION for file mapping
        |
        v
Program Output (files, reports, screens)

2.10.2 What Each Division Contributes

  • IDENTIFICATION DIVISION: The program name becomes the module name in the object file and the entry point name for CALL resolution.
  • ENVIRONMENT DIVISION: File assignments are resolved at compile time (for validation) and at run time (for actual file access). The CONFIGURATION SECTION may affect code generation (e.g., collating sequences, debugging mode).
  • DATA DIVISION: The compiler allocates memory for all data items and generates the code to initialize VALUE clauses. The FILE SECTION determines buffer sizes and record layouts.
  • PROCEDURE DIVISION: The compiler translates COBOL verbs into machine instructions or intermediate code.

2.10.3 Compiling with GnuCOBOL

For readers using GnuCOBOL (the most accessible open-source COBOL compiler), here is the basic compilation workflow:

cobc -x -o myprog myprog.cob        (compile and link to executable)
cobc -x -free -o myprog myprog.cob  (free-format source)
cobc -c myprog.cob                   (compile only, produce .o file)
cobc -x main.o sub1.o sub2.o        (link multiple object files)

Common compiler flags:

Flag Purpose
-x Produce an executable
-m Produce a dynamically loadable module
-free Treat source as free format
-std=cobol85 Enforce COBOL-85 standard
-std=cobol2014 Enforce COBOL-2014 standard
-W Enable warnings
-debug Enable runtime debugging features

2.11 Building a Program from Scratch: A Complete Walkthrough

Let us build a complete COBOL program step by step, explaining each decision along the way. Our program will read an employee file and display a count and total salary.

Step 1: Start with the IDENTIFICATION DIVISION

Every program starts here. We need at minimum the division header and PROGRAM-ID:

       IDENTIFICATION DIVISION.
       PROGRAM-ID.    EMPCOUNT.
       AUTHOR.        CLAUDE TEXTBOOKS.
       DATE-WRITTEN.  2026-02-10.

Step 2: Define the ENVIRONMENT DIVISION

Our program reads one file, so we need a FILE-CONTROL entry:

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT EMPLOYEE-FILE
               ASSIGN TO "EMPLOYEES.DAT"
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-FILE-STATUS.

We omitted the CONFIGURATION SECTION because we do not need special names or debugging mode for this simple program.

Step 3: Define the DATA DIVISION

First, the FILE SECTION for our input file, then WORKING-STORAGE for our variables:

       DATA DIVISION.
       FILE SECTION.
       FD  EMPLOYEE-FILE
           RECORD CONTAINS 50 CHARACTERS.
       01  EMPLOYEE-RECORD.
           05  EMP-ID              PIC 9(5).
           05  EMP-NAME            PIC X(30).
           05  EMP-SALARY          PIC 9(7)V99.
           05  FILLER              PIC X(6).

       WORKING-STORAGE SECTION.
       01  WS-FILE-STATUS          PIC XX    VALUE SPACES.
       01  WS-EOF-FLAG             PIC X     VALUE 'N'.
           88  END-OF-FILE         VALUE 'Y'.
       01  WS-COUNT                PIC 9(5)  VALUE ZEROS.
       01  WS-TOTAL-SALARY         PIC 9(9)V99 VALUE ZEROS.
       01  WS-DISPLAY-SALARY       PIC $$$,$$$,MATH1$,$$$,$$9.99.

procedure division.

0000-main.
    perform 1000-initialize
    perform 2000-process until end-of-file
    perform 3000-finalize
    stop run
    .

1000-initialize.
    open input employee-file
    if ws-file-status not = "00"
        display "ERROR OPENING FILE: " ws-file-status
        stop run
    end-if
    perform 8000-read-employee
    .

2000-process.
    add 1 to ws-count
    add emp-salary to ws-total-salary
    perform 8000-read-employee
    .

3000-finalize.
    move ws-total-salary to ws-display-salary
    display "EMPLOYEES: " ws-count
    display "TOTAL SALARY: " ws-display-salary
    close employee-file
    .

8000-read-employee.
    read employee-file
        at end
            set end-of-file to true
        not at end
            continue
    end-read
    .

Note that the logic and structure are identical. The only differences are cosmetic: no column restrictions, *> for comments, lowercase keywords (by convention, not requirement), and more flexible indentation.


2.15 Summary

The four-division structure is COBOL's defining architectural feature. It enforces a clean separation between program identity, environment configuration, data definitions, and executable logic. This separation is not just organizational tidiness -- it is a design philosophy that has kept COBOL programs maintainable for decades.

Key concepts to remember:

  • IDENTIFICATION DIVISION is the only required division. PROGRAM-ID is its only required paragraph.
  • ENVIRONMENT DIVISION bridges the program and the operating system, particularly through FILE-CONTROL.
  • DATA DIVISION declares all data explicitly. WORKING-STORAGE persists; LOCAL-STORAGE reinitializes; LINKAGE SECTION describes shared data.
  • PROCEDURE DIVISION contains the logic, organized into sections, paragraphs, sentences, and statements.
  • Fixed format uses specific column ranges for specific purposes. Area A (8-11) is for headers and high-level items; Area B (12-72) is for code.
  • Free format removes column restrictions but preserves the division structure.
  • Periods terminate sentences and implicitly close all scope. Prefer explicit scope terminators (END-IF, END-PERFORM, etc.) and minimize periods.
  • Naming conventions with numeric prefixes and descriptive names make programs dramatically more readable.

In the next chapter, we will dive deep into the DATA DIVISION and explore COBOL's rich data description capabilities -- the PICTURE clause, level numbers, and the full range of data types and structures that make COBOL uniquely suited for business data processing.


Chapter 2 code examples are available in the code/ subdirectory. Compile them with GnuCOBOL using cobc -x filename.cob for fixed format or cobc -x -free filename.cob for free format.