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
Your output
Important Rules for Index-Names
They are not data-names: You do not declare them in the WORKING-STORAGE section with a PIC clause. The compiler creates them automatically when it sees INDEXED BY.
Initialization: Their initial value is undefined. You must initialize them before use.
Up to 12 indexes: You can specify up to 12 index-names in a single OCCURS entry.
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.
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
Your output
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 outputcobol
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
You predicted
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.