COBOL Subprograms

A subprogram is a COBOL program that is invoked by another program with the CALL statement. The caller passes parameters with USING (and optionally receives a value with RETURNING). The subprogram receives the parameters in its LINKAGE SECTION and declares them in PROCEDURE DIVISION USING, does its work, and returns with GOBACK or EXIT PROGRAM. This page explains how to write and call subprograms, how the LINKAGE SECTION and USING match the CALL, and how to return control and optional return values.

Explain Like I'm Five: What Is a Subprogram?

Imagine the main program is the boss. When the boss needs a job done (e.g. "calculate the tax"), they call another program (the subprogram), hand it the numbers it needs (parameters), and wait. The subprogram does the work and can give back one answer (the return value) and can also change the numbers it was given (if they were passed by reference). When it is done, it says "I\'m done" (GOBACK) and the boss continues. So a subprogram is a helper program that the main program calls, gives input to, and gets results from.

Calling a Subprogram: CALL

The calling program uses the CALL statement (standard COBOL; not EXEC CICS). The syntax is CALL identifier-or-literal [USING argument-1 ...] [RETURNING identifier]. The identifier or literal is the program name (e.g. CALL 'SUBPROG' or CALL WS-PGM-NAME). The USING list gives the arguments: data items or literals that the subprogram will receive. The order and number must match the subprogram\'s PROCEDURE DIVISION USING. RETURNING is optional and names the data item that will receive the subprogram\'s return value (if the subprogram uses RETURNING). After the CALL, when the subprogram returns, execution continues at the next statement. If the called program is not found or abends, behavior depends on ON OVERFLOW, ON EXCEPTION, or the default for the compiler.

cobol
1
2
3
4
5
6
7
8
*> Calling program 01 WS-AMT PIC 9(7)V99. 01 WS-RATE PIC 9(2)V99. 01 WS-TAX PIC 9(7)V99. CALL 'CALCTAX' USING WS-AMT, WS-RATE, WS-TAX *> Or: CALL 'CALCTAX' USING BY REFERENCE WS-AMT BY CONTENT WS-RATE *> and return value: CALL 'GETCODE' RETURNING WS-CODE

The LINKAGE SECTION in the Subprogram

The called program must define every parameter it receives in the LINKAGE SECTION. The LINKAGE SECTION appears in the DATA DIVISION and contains 01- or 77-level entries that describe the parameters. These items do not have their own storage; they map to the storage of the corresponding arguments in the CALL. So the PICTURE (and length) of each linkage item should match (or be compatible with) the caller\'s argument. The order of the linkage items must match the order of the USING list in PROCEDURE DIVISION and the order of the arguments in the CALL. If the caller passes three arguments, the subprogram must have three linkage items and PROCEDURE DIVISION USING with three parameters.

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*> Called program CALCTAX DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-RESULT PIC 9(7)V99. LINKAGE SECTION. 01 LNK-AMOUNT PIC 9(7)V99. 01 LNK-RATE PIC 9(2)V99. 01 LNK-TAX PIC 9(7)V99. PROCEDURE DIVISION USING LNK-AMOUNT, LNK-RATE, LNK-TAX. MAIN-PARA. COMPUTE WS-RESULT = LNK-AMOUNT * LNK-RATE MOVE WS-RESULT TO LNK-TAX GOBACK.

Here the caller passes amount, rate, and a field for the result (tax). The subprogram computes the tax and moves it to LNK-TAX; because parameters are usually BY REFERENCE, the caller\'s WS-TAX is updated.

PROCEDURE DIVISION USING and RETURNING

The subprogram header must list the parameters in the same order as the LINKAGE SECTION: PROCEDURE DIVISION USING param1, param2, ... Optionally add RETURNING return-item. The return item can be in the LINKAGE SECTION (some compilers) or in WORKING-STORAGE. When the subprogram executes GOBACK or EXIT PROGRAM, the current value of the return item is copied back to the caller\'s RETURNING identifier. So the subprogram acts like a function that returns one value. The caller uses CALL 'name' RETURNING ws-item. If you use both USING and RETURNING, the order is USING list first, then RETURNING.

Returning Control: GOBACK and EXIT PROGRAM

GOBACK returns control to the caller. When executed in a called program, execution resumes at the statement after the CALL in the calling program. When executed in the main program (the one that was not CALLed), GOBACK has the same effect as STOP RUN: the run unit ends. EXIT PROGRAM is a single statement that returns from a subprogram; it does not take a RETURNING phrase (return values are set in the return item before executing EXIT PROGRAM). Prefer GOBACK for clarity and consistency. Do not use STOP RUN in a subprogram to return to the caller—that can terminate the entire run unit. Use GOBACK (or EXIT PROGRAM) so that only the subprogram exits and the caller continues.

Parameter Passing: BY REFERENCE, BY CONTENT, BY VALUE

By default, parameters are passed BY REFERENCE: the subprogram receives the address of the argument, so it can read and modify it and the caller sees the changes. BY CONTENT means the caller passes a copy; the subprogram can change its copy but the caller\'s data is unchanged. BY VALUE passes the value (semantics are implementation-dependent; often used for small values or literals). You can specify the passing method in the CALL: CALL 'prog' USING BY REFERENCE A BY CONTENT B BY VALUE 1. You may also be able to specify it in the subprogram\'s PROCEDURE DIVISION USING (e.g. USING BY REFERENCE param1 BY CONTENT param2). Check your compiler.

Passing methods
MethodMeaningWhen to use
BY REFERENCE (default)Address of the argument is passed. Subprogram can read and modify; caller sees changes.When the subprogram should update the argument or for large data.
BY CONTENTA copy of the value is passed. Subprogram can change its copy but the caller's data is unchanged.When the caller's data must not be modified.
BY VALUEValue is passed (implementation-dependent). Often used for small values or literals.When passing constants or when the subprogram does not need to change the argument.

Nested Calls

A subprogram can call another subprogram. The second program has its own LINKAGE SECTION and PROCEDURE DIVISION USING/RETURNING and returns with GOBACK to the first subprogram, which then returns to the original caller. The call stack can be several levels deep. Each level must correctly match its CALL arguments to its LINKAGE SECTION and PROCEDURE DIVISION. Recursive calls (a program calling itself) are allowed only if the program is compiled with the RECURSIVE attribute (or equivalent); otherwise the behavior is undefined.

Step-by-Step: Writing a Subprogram

  1. In the DATA DIVISION, add a LINKAGE SECTION. Define one 01 (or 77) for each parameter, with PICTURE and length matching what the caller will pass. Order must match the CALL.
  2. If the subprogram returns a value, define the return item (in LINKAGE or WORKING-STORAGE as allowed) and add RETURNING return-item to PROCEDURE DIVISION.
  3. Write PROCEDURE DIVISION USING param1, param2, ... (and RETURNING return-item if used). Use the parameter names (linkage names) in your logic.
  4. Before returning, set the return value (if any) into the return item. Then execute GOBACK (or EXIT PROGRAM). Do not use STOP RUN.

Step-by-Step: Calling a Subprogram

  1. Ensure the data items you will pass (and the one that will receive the return value, if any) are defined with the correct PICTURE and length.
  2. Set any input values into those items. Then issue CALL 'program-name' USING arg1, arg2, ... (and RETURNING result-item if the subprogram returns a value).
  3. After the CALL returns, check the result. If parameters were BY REFERENCE, the subprogram may have updated them; if RETURNING was used, the return value is in the result item.

Best Practices

Test Your Knowledge

Test Your Knowledge

1. Parameters in the subprogram must be defined in:

  • WORKING-STORAGE
  • FILE SECTION
  • LINKAGE SECTION
  • LOCAL-STORAGE

2. To return from a subprogram to the caller you use:

  • STOP RUN
  • GOBACK or EXIT PROGRAM
  • RETURN
  • CALL BACK

3. BY REFERENCE means:

  • The subprogram cannot change the data
  • The address is passed; changes in the subprogram are visible to the caller
  • Only one byte is passed
  • The program is called once