Showing posts with label CALL USING. Show all posts
Showing posts with label CALL USING. Show all posts

Sunday, 22 September 2013

COBOL Called Subprogram: LINKAGE and USING Example

CALL 'CALCTAX' USING WS-GROSS-PAY WS-TAX
    ON EXCEPTION
        DISPLAY 'CALCTAX IS NOT AVAILABLE'
END-CALL

A COBOL called subprogram receives control when the caller executes CALL. In this example, the calling program passes gross pay and tax fields by reference. The subprogram describes those arguments in its LINKAGE SECTION, names them in PROCEDURE DIVISION USING, calculates the tax, and returns control with GOBACK.

COBOL Called Subprogram LINKAGE and USING Example showing CALL, LINKAGE SECTION, and GOBACK flow
The caller passes arguments with CALL USING; the subprogram maps them in LINKAGE and returns with GOBACK.

Complete calling-program example

The caller owns the actual storage for WS-GROSS-PAY and WS-TAX. Because BY REFERENCE is the default, CALCTAX can update the caller's tax field directly.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PAYROLL1.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-GROSS-PAY       PIC S9(7)V99 COMP-3
                              VALUE +0025000.00.
       01  WS-TAX             PIC S9(7)V99 COMP-3
                              VALUE ZERO.

       PROCEDURE DIVISION.
           CALL 'CALCTAX' USING WS-GROSS-PAY WS-TAX
               ON EXCEPTION
                   DISPLAY 'CALCTAX IS NOT AVAILABLE'
                   MOVE ZERO TO WS-TAX
           END-CALL

           DISPLAY 'GROSS PAY: ' WS-GROSS-PAY
           DISPLAY 'TAX:       ' WS-TAX
           GOBACK.

The literal 'CALCTAX' names the target program. Whether a literal call is static or dynamic depends on compiler and link-edit choices such as DYNAM, NODYNAM, and DLL handling. This article keeps the focus on the source contract between the caller and callee; the COBOL static-call guide owns the binding and performance intent.

Complete called-subprogram example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CALCTAX.

       DATA DIVISION.
       LINKAGE SECTION.
       01  LK-GROSS-PAY       PIC S9(7)V99 COMP-3.
       01  LK-TAX             PIC S9(7)V99 COMP-3.

       PROCEDURE DIVISION USING LK-GROSS-PAY LK-TAX.
           COMPUTE LK-TAX ROUNDED = LK-GROSS-PAY * 0.20
           GOBACK.

The LINKAGE SECTION describes the fields supplied by another program. It does not allocate storage for these arguments. At entry, PROCEDURE DIVISION USING maps the first caller argument to LK-GROSS-PAY and the second to LK-TAX. The names do not need to match across programs, but their positions and data descriptions must be compatible.

Contract check: compare caller and callee definitions side by side. For this example, both sides use signed packed decimal fields with PIC S9(7)V99 COMP-3.

How CALL USING maps arguments

PositionCaller argumentSubprogram parameterRequired check
1WS-GROSS-PAYLK-GROSS-PAYSame business value and compatible size, sign, scale, and USAGE.
2WS-TAXLK-TAXWritable output passed BY REFERENCE with a compatible packed-decimal definition.

COBOL associates the lists by position, not by data-name. Reversing the two arguments can produce a wrong calculation even though the statement compiles. A different length or USAGE can make the called program read the wrong bytes, overwrite adjacent storage, or raise a runtime condition.

Do not add a LINKAGE item to the PROCEDURE DIVISION USING list unless the caller supplies the matching position. Likewise, do not add a caller argument without updating the callee contract. When programs are maintained in separate source libraries, document the shared interface in a copybook or interface specification and rebuild every affected component.

BY REFERENCE, BY CONTENT, and BY VALUE

BY REFERENCE is assumed when no mode is coded. The called program works with the caller's storage, which is why CALCTAX can place the result in WS-TAX.

CALL 'CALCTAX'
    USING BY REFERENCE WS-GROSS-PAY WS-TAX
END-CALL

BY CONTENT gives the subprogram a copy for that parameter. Changes to the corresponding callee data item do not change the caller's argument. Passing WS-TAX BY CONTENT would therefore lose the intended output when control returns.

BY VALUE passes a value rather than a reference to the sending field. It is common when the target follows a non-COBOL linkage convention, and COBOL-to-COBOL use requires compatible BY VALUE handling in the subprogram header. For the full comparison and syntax, use the COBOL CALL parameter modes guide.

Literal and identifier calls

01  WS-PROGRAM-NAME     PIC X(8) VALUE 'CALCTAX'.

CALL WS-PROGRAM-NAME USING WS-GROSS-PAY WS-TAX
    ON EXCEPTION
        DISPLAY 'PROGRAM NOT FOUND: ' WS-PROGRAM-NAME
END-CALL

A CALL identifier chooses the program name at run time and is dynamic in Enterprise COBOL for z/OS. It is useful when configuration or record content selects one of several subprograms. Validate the identifier value before the call and ensure the resulting program object is available through the site's runtime search path.

Do not mix assumptions: a literal target is not automatically static. Compiler options and binding determine how a literal call is resolved; an identifier call is dynamic.

Return control with GOBACK

In a called program, GOBACK returns control to the statement following the active CALL. EXIT PROGRAM also returns from a called program, while STOP RUN ends the run unit rather than performing an ordinary subprogram return.

A called program usually retains its WORKING-STORAGE state after GOBACK or EXIT PROGRAM. If a counter must start at zero on every invocation, initialize it explicitly, use LOCAL-STORAGE where suitable, or apply an approved INITIAL/CANCEL design. See Working Storage versus Local Storage and COBOL program termination and reentry for those separate lifecycle decisions.

Handle an unavailable dynamic subprogram

ON EXCEPTION handles a failure to make a dynamically called program available on its initial load. Typical checks include the program-name value, binder NAME or ALIAS, load-library concatenation, deployment member, and access to the library.

Boundary: ON EXCEPTION does not catch a data exception, protection exception, or application error after CALCTAX begins executing. Use normal validation, runtime diagnostics, and site error handling for failures inside the called program.

Common called-subprogram failures

SymptomLikely causePractical check
Output remains zeroOutput passed BY CONTENT or callee never moved/computed itConfirm BY REFERENCE and trace the matching callee parameter.
Numeric data exception or corrupted fieldCaller and callee definitions disagreeCompare order, byte length, PICTURE, USAGE, sign, and scale.
ON EXCEPTION executesDynamic target cannot be made availableCheck identifier value, binder name, load library, deployment, and access.
ON EXCEPTION does not catch an abendTarget loaded, then failed during executionRead the Language Environment and system diagnostics for the actual failure.
Second call starts with old valuesSubprogram WORKING-STORAGE retained its last-used stateInitialize state or review LOCAL-STORAGE, INITIAL, and CANCEL behavior.
Caller never resumesSubprogram executes STOP RUN or branches incorrectlyUse GOBACK or EXIT PROGRAM for an ordinary return and trace the final path.

Caller and subprogram checklist

  • Define one clear interface and keep the CALL and PROCEDURE DIVISION USING lists in the same order.
  • Match PICTURE, USAGE, sign, scale, and expected length for every position.
  • Use BY REFERENCE for outputs that the callee must return through an argument.
  • Use END-CALL to make the scope clear when ON EXCEPTION is present.
  • Return from the subprogram with GOBACK or EXIT PROGRAM, not STOP RUN.
  • Confirm how compiler and binder options resolve literal calls.
  • Place dynamically called program objects in the approved runtime library.
  • Test first-call and repeated-call behavior so retained state is visible.

The COBOL application-structure guide explains how main programs, subprograms, and the run unit fit together.

Official IBM references

COBOL called subprogram FAQ

Does a COBOL called subprogram allocate storage for LINKAGE items?

No. LINKAGE SECTION entries describe data made available by the caller; they do not reserve storage for those arguments. The PROCEDURE DIVISION USING list establishes addressability when the subprogram is entered.

Must CALL USING arguments match PROCEDURE DIVISION USING parameters?

Yes. They correspond by position, so keep the count, order, size, PICTURE, USAGE, and sign compatible. A mismatch can corrupt data or cause a runtime failure even when both programs compile.

Is CALL BY REFERENCE the default in Enterprise COBOL?

Yes. When no passing mode is stated, BY REFERENCE is assumed. The called program works with the caller's storage, so changes to an output parameter are visible after control returns.

What does ON EXCEPTION handle on a dynamic CALL?

It handles failure to make the called program available on its initial load, such as when the program object cannot be located. It does not catch an abend or application error that occurs after the called program begins running.

When a CALL fails in production, compare the two parameter lists before changing program logic; one wrong position or data definition can explain the entire failure.

New In-feed ads