Key Takeaways — Chapter 22: CALL and Subprogram Linkage

Core Concepts

  1. The CALL statement transfers control from a calling program to a subprogram. Parameters are passed via the USING clause and matched positionally — not by name.

  2. Static CALL resolves the subprogram at link-edit time, embedding it in the caller's load module. It is faster but less flexible — any change to the subprogram requires relinking the caller.

  3. Dynamic CALL resolves the subprogram at runtime by searching load libraries. It is slightly slower on first invocation but allows independent deployment and memory management.

  4. A CALL using an identifier (data item) is always dynamic, regardless of compiler options. A CALL using a literal may be static or dynamic depending on the DYNAM/NODYNAM compiler option.

  5. The LINKAGE SECTION declares the layout of parameters received from the caller. It does not allocate storage — it maps onto the caller's storage.

  6. PROCEDURE DIVISION USING establishes the correspondence between LINKAGE SECTION items and the parameters in the CALL USING clause.

Critical Rules

  1. Always use GOBACK in subprograms. STOP RUN terminates the entire run unit. EXIT PROGRAM is the legacy equivalent of GOBACK for subprograms.

  2. Always use copybooks for interface definitions. When both calling and called programs COPY the same member, parameter mismatches are eliminated.

  3. Always code ON EXCEPTION for dynamic CALLs in production programs. Without it, a missing program causes an unhandled ABEND.

  4. Parameter size mismatches cause storage overlays — one of the hardest bugs to diagnose. The called program may write beyond the bounds of the actual parameter, corrupting adjacent storage in the caller.

Design Patterns

  1. Standardized return codes (0=success, 4=warning, 8=error, 12+=severe) provide a consistent way for subprograms to communicate status.

  2. The CANCEL statement releases a dynamically loaded subprogram from memory and reinitializes its WORKING-STORAGE on the next call. Use it to free memory or pick up updated modules.

  3. Dynamic dispatch — building program names at runtime from data values — enables extensible systems where new functionality can be added without modifying the caller.

  4. Modular decomposition transforms unmaintainable monoliths into systems of focused, independently testable, and independently deployable components.

The Big Picture

  1. Modular design is the foundation of incremental modernization. Individual modules can be rewritten, optimized, or replaced — even in different languages — without disrupting the rest of the system. This is the essence of The Modernization Spectrum theme: you do not have to rewrite everything at once.