Subprograms & the CALL Statement

COBOL Fundamentals

Chapter 9 · Subprograms & the CALL Statement

Every real program written so far has been one self-contained unit. Real COBOL systems are routinely built from many separately compiled programs calling one another — CALL is the real statement that hands control from one to the next, and back again.

CALL: Static vs. Dynamic

A real CALL comes in two genuinely different forms:

CALL "BALCHECK" USING WS-BALANCE WS-VALID-FLAG.

A literal name in quotes, like "BALCHECK" above, is a real static call — the specific subprogram is fixed at compile time. A real dynamic call uses a data item instead of a literal, so which program actually runs is only decided while the program is genuinely running:

MOVE "BALCHECK" TO WS-PROGRAM-NAME. CALL WS-PROGRAM-NAME USING WS-BALANCE WS-VALID-FLAG.

Passing Parameters: BY REFERENCE, BY CONTENT & BY VALUE

ModeWhat Genuinely Happens
BY REFERENCE (real default)The called program's item occupies the exact same real storage as the caller's — a change made inside the subprogram genuinely changes the caller's own data
BY CONTENTThe called program receives a real copy; nothing it does can change the caller's original data
BY VALUEPasses the real value itself rather than any storage reference at all, working on a genuine temporary copy
A Genuinely Easy Assumption to Get Wrong Because BY REFERENCE is the real default whenever no keyword is written at all, a subprogram that only reads a parameter to make a decision can still accidentally overwrite the caller's genuine data with one careless MOVE — there's no automatic protection unless BY CONTENT or BY VALUE is deliberately specified.

The LINKAGE SECTION: Receiving Parameters

A called subprogram doesn't declare its incoming parameters in WORKING-STORAGE. It declares them in a real, separate LINKAGE SECTION — real storage "for parameters and the return value," genuinely matched by position, not by name, against the caller's own CALL ... USING list:

IDENTIFICATION DIVISION. PROGRAM-ID. BALCHECK. DATA DIVISION. LINKAGE SECTION. 01 LS-BALANCE PIC S9(7)V99. 01 LS-VALID-FLAG PIC X(1). PROCEDURE DIVISION USING LS-BALANCE LS-VALID-FLAG. IF LS-BALANCE < 0 MOVE "N" TO LS-VALID-FLAG ELSE MOVE "Y" TO LS-VALID-FLAG END-IF. GOBACK.
Names Don't Have to Match — Position Does The caller's field is WS-BALANCE; the subprogram's own matching field is LS-BALANCE — genuinely different names. What has to match is the real order and number of items: the first item in PROCEDURE DIVISION USING receives whatever the first item in CALL ... USING was, regardless of what either one is actually called.

Returning Control: GOBACK's Real Two Faces

GOBACK genuinely behaves differently depending on where it's used — it doesn't always mean the same thing:

Where GOBACK AppearsWhat It Genuinely Does
In a called subprogramBehaves like EXIT PROGRAM — returns control to the caller, right after the CALL statement
In a main programBehaves like STOP RUN — ends the whole application

STOP RUN itself is never appropriate inside a real subprogram meant to return — it would end the entire application rather than hand control back to whatever called it.

Hands-On Exercises

Exercise 1

Using this chapter's own real BALCHECK example, explain in your own words why WS-VALID-FLAG in the calling program genuinely ends up holding "Y" or "N" after the CALL, even though the subprogram itself only ever assigns a value to LS-VALID-FLAG.

📄 View solution
Exercise 2

A colleague writes CALL "BALCHECK" USING WS-VALID-FLAG WS-BALANCE, reversing the real order from this chapter's own example, without changing BALCHECK's own LINKAGE SECTION or PROCEDURE DIVISION USING at all. Using this chapter's own real material, explain in your own words what genuinely goes wrong.

📄 View solution
Exercise 3

Using this chapter's own real material, explain in your own words the genuine difference between using GOBACK inside BALCHECK versus accidentally writing STOP RUN there instead.

📄 View solution

Chapter 9 Quick Reference

  • CALL "literal" — real static call, fixed at compile time; CALL identifier — real dynamic call, decided at runtime
  • BY REFERENCE (real default) — shared real storage, changes propagate back; BY CONTENT — a real copy, caller's data untouched; BY VALUE — a real value copy, no storage reference at all
  • LINKAGE SECTION — where a subprogram declares its incoming parameters, matched by real position (not name) to CALL ... USING
  • PROCEDURE DIVISION USING — names the LINKAGE SECTION items a called program actually receives, in order
  • GOBACK — real context-dependent: acts like EXIT PROGRAM in a subprogram, like STOP RUN in a main program