INDEXED BY and SET

COBOL GnuCOBOL 3.2.0 ยท โœ“ verified by execution on 2026-08-16

When working with tables (OCCURS) in COBOL, you can use regular data items (like a PIC 9 integer) as subscripts to access elements. However, COBOL provides a much more efficient mechanism specifically designed for table navigation: indexing.

Indexing uses special, compiler-generated registers called index-names to point to elements in a table. Because index-names store the physical memory offset (displacement) from the beginning of the table rather than a simple 1-based occurrence number, they are significantly faster for the compiler to process.

Defining Index-Names

You define an index-name by adding the INDEXED BY phrase directly to the OCCURS clause.

cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. IDX-BASIC.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  FRUIT-TABLE.
           05 FRUIT-ITEM PIC X(10) OCCURS 3 TIMES INDEXED BY FRUIT-IDX.
       PROCEDURE DIVISION.
           MOVE "APPLE" TO FRUIT-ITEM(1)
           MOVE "BANANA" TO FRUIT-ITEM(2)
           MOVE "CHERRY" TO FRUIT-ITEM(3)
           
           SET FRUIT-IDX TO 2
           DISPLAY FRUIT-ITEM(FRUIT-IDX)
           STOP RUN.
Output
BANANA    

Important Rules for Index-Names

Memory Displacement vs. Occurrence Number

The primary difference between a normal subscript and an index-name is what they actually store. A subscript stores the occurrence number (e.g., 1, 2, 3). An index-name stores the physical byte offset from the start of the table.

"APPLE " "BANANA " "CHERRY " Subscript: 1 Subscript: 2 Subscript: 3 Offset 0 Offset 10 Offset 20 FRUIT-IDX (Value = 10)

Because index-names are not standard data items, you cannot use a MOVE statement to set their values, and you cannot use ADD or SUBTRACT to change them. You must use the SET statement.

The SET Statement

The SET statement is the only standard way to initialize, increment, or decrement index-names. It handles the behind-the-scenes math of converting between occurrence numbers (integers) and memory offsets.

cobol โœ“ verified output
       IDENTIFICATION DIVISION.
       PROGRAM-ID. SET-INDEX.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  FRUIT-TABLE.
           05 FRUIT-ITEM PIC X(10) OCCURS 3 TIMES INDEXED BY FRUIT-IDX.
       PROCEDURE DIVISION.
           MOVE "APPLE" TO FRUIT-ITEM(1)
           MOVE "BANANA" TO FRUIT-ITEM(2)
           MOVE "CHERRY" TO FRUIT-ITEM(3)
           
           *> Initialize the index to the 1st occurrence (Offset 0)
           SET FRUIT-IDX TO 1
           DISPLAY "Element 1: " FRUIT-ITEM(FRUIT-IDX)
           
           *> Increment the index by 2 occurrences (Offset 20)
           SET FRUIT-IDX UP BY 2
           DISPLAY "Element 3: " FRUIT-ITEM(FRUIT-IDX)
           
           *> Decrement the index by 1 occurrence (Offset 10)
           SET FRUIT-IDX DOWN BY 1
           DISPLAY "Element 2: " FRUIT-ITEM(FRUIT-IDX)
           
           STOP RUN.
Output
Element 1: APPLE     
Element 3: CHERRY    
Element 2: BANANA    

Converting Between Data Items and Index-Names

Sometimes you need to store the current position of an index-name in a regular data item, or initialize an index-name using a regular data item. The SET statement allows this two-way conversion.

Try to predict the output of this program based on how SET converts occurrences!

Predict the output cobol

Read the code. What exactly will it print? Commit to an answer before you look.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CONV.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  TAB.
           05 ITEM PIC X OCCURS 3 INDEXED BY IDX.
       01  CURR-POS PIC 9.
       PROCEDURE DIVISION.
           SET IDX TO 3
           SET CURR-POS TO IDX
           DISPLAY "POS=" CURR-POS
           STOP RUN.
Output
POS=3

Check yourself

How must you define an index-name used in an INDEXED BY clause?

Reveal answer

You do not define it; the compiler creates it automatically. โ€” The INDEXED BY phrase automatically creates the internal index register; explicitly defining it with a PIC clause will cause a compiler error.

Which statement is valid in standard COBOL for incrementing an index-name?

Reveal answer

SET IDX UP BY 1 โ€” Standard math operations like ADD or COMPUTE do not work on index-names. You must use the SET statement to manipulate them.

What does an index-name internally represent in COBOL?

Reveal answer

The physical memory displacement (offset) from the beginning of the table. โ€” An index-name stores the physical byte offset instead of the occurrence number, making table lookups faster for the compiler.

Challenges

Challenge 1 +20 XP

Create a table of 5 days of the week indexed by DAY-IDX. Initialize the first three elements to MON, TUE, WED. Set the index to 1, then use SET UP BY to advance it to 3, and display the third element.

cobol โœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real โ€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 โ€” expects "WED\n"
Need a hint? (โˆ’25% XP)

Use INDEXED BY DAY-IDX in your OCCURS clause. Then use SET DAY-IDX TO 1, followed by SET DAY-IDX UP BY 2.

Show solution (0 XP)
       IDENTIFICATION DIVISION.
       PROGRAM-ID. CHAL1.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  DAY-TABLE.
           05 DAY-ITEM PIC X(3) OCCURS 5 TIMES INDEXED BY DAY-IDX.
       PROCEDURE DIVISION.
           MOVE "MON" TO DAY-ITEM(1)
           MOVE "TUE" TO DAY-ITEM(2)
           MOVE "WED" TO DAY-ITEM(3)
           SET DAY-IDX TO 1
           SET DAY-IDX UP BY 2
           DISPLAY DAY-ITEM(DAY-IDX)
           STOP RUN.

Challenge 2 +20 XP

Extract the occurrence number from an index-name into a regular PIC 9 data item and display it. Set the index to 4, then extract its value to `CURRENT-POS`.

cobol โœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real โ€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 โ€” expects "4\n"
Need a hint? (โˆ’25% XP)

You can use SET data-item TO index-name to convert the internal index displacement back into a regular integer.

Show solution (0 XP)
       IDENTIFICATION DIVISION.
       PROGRAM-ID. CHAL2.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  DAY-TABLE.
           05 DAY-ITEM PIC X(3) OCCURS 5 TIMES INDEXED BY DAY-IDX.
       01  CURRENT-POS PIC 9.
       PROCEDURE DIVISION.
           SET DAY-IDX TO 4
           SET CURRENT-POS TO DAY-IDX
           DISPLAY CURRENT-POS
           STOP RUN.

๐Ÿž Bug Hunt +20 XP

Identify why this program fails to compile and fix the error.

This code runs. It just does the wrong thing. Read it, find the defect, fix it โ€” the tests below decide when you are right.

cobol โœ“ solution verified at build time

COBOL has no in-browser runtime, so this one is pen-and-paper: work out what the fixed code should be, then open the solution and compare. The expected output below is real โ€” it came from compiling the solution with GnuCOBOL when this page was built.

  • Test 1 โ€” expects "BANANA \n"
Need a hint? (โˆ’25% XP)

Remove the explicit `01 FRUIT-IDX PIC 9` declaration (the compiler creates it automatically), and use SET UP BY instead of standard math operations like ADD.

Show solution (0 XP)
       IDENTIFICATION DIVISION.
       PROGRAM-ID. BUGGY.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  FRUIT-TABLE.
           05 FRUIT-ITEM PIC X(10) OCCURS 3 TIMES INDEXED BY FRUIT-IDX.
       PROCEDURE DIVISION.
           MOVE "APPLE" TO FRUIT-ITEM(1)
           MOVE "BANANA" TO FRUIT-ITEM(2)
           SET FRUIT-IDX TO 1
           SET FRUIT-IDX UP BY 1
           DISPLAY FRUIT-ITEM(FRUIT-IDX)
           STOP RUN.