COBOL GnuCOBOL 3.2 ·
✓ verified by execution on 2026-08-16
When writing a large COBOL application, you will naturally divide your logic into multiple programs. One program will act as the controller, and it will CALL other subprograms to perform specific tasks.
However, COBOL gives you two entirely different ways to connect these programs together: Static Calls and Dynamic Calls.
Static Subprograms
A static subprogram is combined with the calling program when the code is compiled. The compiler (and the linker) takes the object code of the subprogram and embeds it directly inside the executable of the main program.
When you use a literal string in your CALL statement (like CALL 'SUBPROG'), the compiler often resolves this as a static call.
cobol✓ verified output
ID DIVISION. PROGRAM-ID. MAINPROG. PROCEDURE DIVISION. CALL 'SUBPROG'. STOP RUN. END PROGRAM MAINPROG. ID DIVISION. PROGRAM-ID. SUBPROG. PROCEDURE DIVISION. DISPLAY 'STATIC CALL EXECUTED'. EXIT PROGRAM. END PROGRAM SUBPROG.
Output
STATIC CALL EXECUTED
Your output
The advantage of a static call is speed—there is no overhead to find the subprogram when the CALL runs because it is already part of the same file.
Dynamic Subprograms
A dynamic subprogram is kept in a separate file on disk. When the CALL statement is reached, the runtime system searches for the subprogram, loads it into memory, and then executes it.
When you use a variable for the subprogram name, the compiler treats it as a dynamic call because it doesn’t know the name until runtime.
cobol✓ verified output
ID DIVISION. PROGRAM-ID. MAINPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 SUB-NAME PIC X(10) VALUE 'SUBPROG'. PROCEDURE DIVISION. CALL SUB-NAME. STOP RUN. END PROGRAM MAINPROG. ID DIVISION. PROGRAM-ID. SUBPROG. PROCEDURE DIVISION. DISPLAY 'DYNAMIC CALL EXECUTED'. EXIT PROGRAM. END PROGRAM SUBPROG.
Output
DYNAMIC CALL EXECUTED
Your output
Because the subprogram is separate, you can update and recompile a dynamic subprogram without recompiling the main program! However, this flexibility comes with a slight performance cost when the program is first loaded.
State Retention
One of the most important concepts to understand is what happens when you call a subprogram multiple times.
When a subprogram is called, it executes, and when it reaches EXIT PROGRAM, control returns to the caller. But the subprogram stays in memory.
Let’s see what happens if the subprogram updates a variable in its WORKING-STORAGE.
Predict the outputcobol
Read the code. What exactly will it print? Commit to an answer before you look.
PROGRAM-ID. MAINPROG. PROCEDURE DIVISION. CALL 'SUBPROG'. CALL 'SUBPROG'. STOP RUN. END PROGRAM MAINPROG. PROGRAM-ID. SUBPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 CTR PIC 9 VALUE 0. PROCEDURE DIVISION. ADD 1 TO CTR. DISPLAY 'STATIC RUN ' CTR. EXIT PROGRAM. END PROGRAM SUBPROG.
Output
STATIC RUN 1
STATIC RUN 2
You predicted
Because the subprogram stays in memory, its WORKING-STORAGE retains the value from the first call. It does not reset its values when you call it again!
The CANCEL Statement
If you want to reset a dynamically called subprogram so its WORKING-STORAGE is reinitialized, you must use the CANCEL statement.
CANCEL unloads the dynamic subprogram from memory. The next time you CALL it, it will be loaded fresh from disk, and all variables will return to their initial VALUE declarations.
cobol✓ verified output
ID DIVISION. PROGRAM-ID. MAINPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 SUB-NAME PIC X(10) VALUE 'SUBPROG'. PROCEDURE DIVISION. CALL SUB-NAME. CANCEL SUB-NAME. CALL SUB-NAME. STOP RUN. END PROGRAM MAINPROG. ID DIVISION. PROGRAM-ID. SUBPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 CTR PIC 9 VALUE 0. PROCEDURE DIVISION. ADD 1 TO CTR. DISPLAY 'RUN ' CTR. EXIT PROGRAM. END PROGRAM SUBPROG.
Output
RUN 1
RUN 1
Your output
If we had omitted the CANCEL SUB-NAME statement, the output would have been RUN 1 followed by RUN 2.
Note on Static Calls: You cannot CANCEL a static subprogram. Because it is part of the main executable, it cannot be unloaded from memory. If you need a subprogram’s state to reset on every call, it must be compiled dynamically, or you must pass it data through the LINKAGE SECTION instead of storing state internally.
Check yourself
What happens when you use a static CALL in COBOL?
Reveal answer
The subprogram is compiled and linked into the main program's executable file. — Static calls are resolved at compile time, meaning the subprogram's object code is embedded directly into the main program's executable.
Why might a dynamic CALL introduce slightly more overhead than a static CALL?
Reveal answer
Because the main program must search for and load the separate module at runtime. — Dynamic calls load a separate module at runtime. This introduces a slight overhead as the OS must locate and load the executable file into memory.
What is the purpose of the CANCEL statement in COBOL?
Reveal answer
To unload a dynamically loaded subprogram from memory and reset its state. — The CANCEL statement removes a dynamically loaded subprogram from memory. If it is called again, it is reloaded, effectively resetting its WORKING-STORAGE state.
If you dynamically call a subprogram twice without using CANCEL, what happens to its WORKING-STORAGE?
Reveal answer
The state is retained from the first call. — Unless explicitly CANCELed, a dynamically called subprogram remains in memory and retains its WORKING-STORAGE state between calls.
Challenges
Challenge 1 +50 XP
Call a subprogram dynamically using a variable name, then display 'DONE'.
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 "IN SUB\nDONE"
Show solution (0 XP)
*> COBOL Program ID DIVISION. PROGRAM-ID. MAINPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 PROG-VAR PIC X(10) VALUE 'THE-SUB'. PROCEDURE DIVISION. CALL PROG-VAR. DISPLAY 'DONE'. STOP RUN. END PROGRAM MAINPROG. ID DIVISION. PROGRAM-ID. THE-SUB. PROCEDURE DIVISION. DISPLAY 'IN SUB'. EXIT PROGRAM. END PROGRAM THE-SUB.
🐞 Bug Hunt+50 XP
Bug Hunt: This program calls a subprogram twice, expecting the counter to be 1 both times. Run it, see the bug, and fix the code so the counter resets.
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 "1\n1"
Show solution (0 XP)
*> COBOL Program ID DIVISION. PROGRAM-ID. MAINPROG. DATA DIVISION. WORKING-STORAGE SECTION. 01 SUB-VAR PIC X(10) VALUE 'SUB'. PROCEDURE DIVISION. CALL SUB-VAR. CANCEL SUB-VAR. CALL SUB-VAR. STOP RUN. END PROGRAM MAINPROG. ID DIVISION. PROGRAM-ID. SUB. DATA DIVISION. WORKING-STORAGE SECTION. 01 CTR PIC 9 VALUE 0. PROCEDURE DIVISION. ADD 1 TO CTR. DISPLAY CTR. EXIT PROGRAM. END PROGRAM SUB.