CALL Statement
- A CALL statement statement is used to transfer the control from one program to another.
- The CALL statement is always coded in the calling or main program, and the program name in the CALL statement is called or subprogram.
- The main program holds its execution until the subprogram completes its execution. This allows for a structured and organized flow of operations.
- Subprograms are mainly designed to complete a common task performed in many programs. By calling the subprogram from where the task needs to be completed, we can avoid code redundancy (coding the same piece of code in multiple locations).
To understand the concept, we assume we have a main program (MAINPROG) and a subprogram (SUBPROG) coded as different programs. The MAINPROG calls the SUBPROG using the CALL statement.
Syntax -
CALL subprogram
[USING variable1, variable2, ...]
[RETURNING variableA, variableB, ...]
[ON EXCEPTION statements-block1]
[NOT ON EXCEPTION statements-block2]
[END-CALL].
END-CALL -
END-CALL is the scope terminator for the CALL statement. If the CALL statement ends with a period, it is not required.
CALL Types -
CALLs are two types based on how the subprogram is called from main program -
- Static Call
- Dynamic call
STATIC CALL -
- STATIC CALL attaches the SUBPROG load module to the MAINPROG load module to increase processing speed.
- The load modules of MAINPROG and SUBPROG are stored together, that reduces the loading time of the SUBPROG load module into the main memory.
Syntax -
CALL "subprogram-name"
Points to Note -
- subprogram-name should be in quotes, and the compiler option should be NODYNAM to make the call as STATIC.
- If SUBPROG is modified, it should be compiled first. Then, MAINPROG should be compiled to update the load module with the new SUBPROG changes. If SUBPROG is not modified, compiling MAINPROG alone is sufficient.
- The load module of MAINPROG using STATIC CALL occupies more space than MAINPROG using DYNAMIC CALL.
- STATIC CALL execution is faster than DYNAMIC CALL.
DYNAMIC CALL -
- DYNAMIC CALL removes the compilation dependency of MAINPROG when the SUBPROG is modified.
- The CALL statement is coded with a variable containing the SUBPROG name to separate the load modules stored independently.
Syntax -
05 WS-SUBPROG PIC X(08) VALUE SPACES.
...
MOVE "SUBPROG" TO WS-SUBPROG.
CALL WS-SUBPROG
Points to Note -
- A CALL statement with a WORKING-STORAGE variable (WS-SUBPROG) with a SUBPROG name makes the call as DYNAMIC.
- The compiler option should be DYNAM while compiling the module.
- If SUBPROG is modified, compiling SUBPROG alone is sufficient.
- DYNAMIC CALL execution is a little slower when compared with STATIC CALL.
- DYNAMIC CALL is the most used one nowadays.
USING phrase -
- USING phrase is used to pass the parameters from MAINPROG (CALL...USING) and receives the same in SUBPROG (PROCEDURE DIVISION USING...).
- We should declare the passing parameters in the WORKING-STORAGE SECTION of MAINPROG and the LINKAGE SECTION of SUBPROG.
- If USING is coded in either MAINPROG or SUBPROG, the other program also should code with it.
- The parameters declaration should match in both MAINPROG and SUBPROG.
USING in MAINPROG -
CALL WS-SUBPROG USING WS-INP1, WS-INP2.
USING in SUBPROG -
PROCEDURE DIVISION USING LS-INP1, LS-INP2.
Passing Parameters -
There are three types of passing parameters from MAINPROG to SUBPROG, and those are -
- BY REFERENCE - BY REFERENCE passes the address of the parameter memory location to the SUBPROG.
- BY CONTENT - BY CONTENT passes the copy of the data to the SUBPROG.
- BY VALUE - BY VALUE is similar to the BY CONTENT and is used to pass the copy of the data to the SUBPROG. It is introduced for communicating with non-COBOL programs.
RETURNING phrase -
- RETURNING phrase is used to return a value from SUBPROG to the MAINPROG.
- It is always coded with PROCEDURE DIVISION of SUBPROG.
- If the RETURNING phrase is coded in SUBPROG, MAINPROG should have the corresponding variable to receive the result.
MAINPROG -
CALL WS-SUBPROG USING WS-INP1, WS-INP2, WS-RESULT.
RETURNING in SUBPROG -
PROCEDURE DIVISION USING LS-INP1, LS-INP2
RETURNING LS-RESULT.
Error Handling -
ON EXCEPTION phrase -
If an exception condition occurs when the SUBPROG is not available to run or if an abend occurs in SUBPROG, control transfers to the set of statements coded with ON EXCEPTION, and then execution continues.
NOT ON EXCEPTION phrase -
If an exception does not occur and the SUBPROG execution is completed successfully, control transfers to the set of statements coded with NOT ON EXCEPTION, and then execution continues.
Practical Example -
Scenario - Static Call from MAINPROG to SUBPROG and receiving the result back from SUBPROG.
MAINPROG -
----+----1----+----2----+----3----+----4----+----5----+
...
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VAR.
05 WS-INP1 PIC 9(02) VALUE 47. *> Input1
05 WS-INP2 PIC 9(02) VALUE 25. *> Input2
05 WS-RESULT PIC 9(04). *> Result Variable
PROCEDURE DIVISION.
...
* Calling subprogram staically with two inputs
* and receiving the result from SUBPROG
CALL "SUBPROG" USING WS-INP1, WS-INP2, WS-RESULT.
DISPLAY "INPUTS: " WS-INP1 ", " WS-INP2.
DISPLAY "RESULTS: " WS-RESULT.
STOP RUN.
SUBPROG -
----+----1----+----2----+----3----+----4----+----5----+
...
DATA DIVISION.
LINKAGE SECTION.
01 LS-INP1 PIC 9(02). *> To receive input1 from MAINPROG
01 LS-INP2 PIC 9(02). *> To receive input2 from MAINPROG
01 LS-RESULT PIC 9(04). *> To send result to MAINPROG
...
*Receiving data from main program CALL statement
PROCEDURE DIVISION USING LS-INP1, LS-INP2, LS-RESULT.
COMPUTE LS-RESULT = LS-INP1 * LS-INP2.
GOBACK.
JCL -
//MATEPKRJ JOB MSGLEVEL=(1,1),NOTIFY=&SYSUID //*********************************************** //* RUN A COBOL PROGRAM //*********************************************** //STEP01 EXEC PGM=MAINPROG //STEPLIB DD DSN=MATEPK.COBOL.LOADLIB,DISP=SHR //SYSOUT DD SYSOUT=*
Output -
INPUTS: 47, 25 RESULTS: 1175