It is often noticed that there is some confusion regarding Static and Dynamic Calls
and considerable confusion regarding the pros and cons of these call types.
When you use the CALL statement in a program that is compiled using the
NODYNAM compiler options, a STATIC CALL occurs. In the static CALL
statement, the COBOL program and all called programs are part of the same load
module. When control is transferred, the called program already resides in storage,
and a branch to it takes place.
Example : CALL “SUBPROG ” USING RECORD-1.
When you use the CALL statement in a program that is compiled using the DYNAM
compiler options or when you use the CALL identifier statement in a program, a
DYNAMIC CALL occurs. In this form of the CALL statement, the called COBOL
subprogram is not link-edited with the main program, but is instead link-edited into
a separate load module, and, at run time, is loaded only when it is required (that is,
when called).
Example : MOVE “SUBPROG ” TO PGM-NAME.
CALL PGM-NAME USING RECORD-1.
Where PGM-NAME is defined in the Working Storage Section.
Things to avoid
Mixing the methods, using both dynamic and static. Confusing, if nothing
else.
Coding the binder INCLUDE statement at SYSLIN when using dynamic
linkage.
Using the COBOL CANCEL statement to force a reload of a previously
loaded program when using dynamic.
Finally, if you need to make both static and dynamic calls from your COBOL
program, compile with the NODYNAM option. In this case, with the CALL literal
statement the called subprogram will be link-edited with the main program into one
load module. The CALL identifier statement results in the dynamic invocation of a
separate load module.
What's new in COBOL for OS/390?
The biggest change you will notice in COBOL for OS/390 (also known as
COBOL/370 or COBOL for MVS) is that you can use "intrinsic functions". These are
special routines written to do specific things such as calculating the square root of
a number, generating a random number, changing a field to upper case characters,
and many other things.
For example:
COMPUTE WS-SQ1 = FUNCTION SQRT(WS-SQ2)
would calculate the square root of the number stored in WS-SQ2 and place it in
WS-SQ1.
Intrinsic functions are built in to COBOL (Note With some compliers you can even
write your own functions - check compiler documentation to see if this is
implemented).
COBOL for OS/390 is Y2K compliant.
COBOL for OS/390 introduces a new feature known as Procedure Pointer fields.
These are pointers to the Program-ID of a non-nested COBOL program, the entry
point of a COBOL program or an entry point to a non-COBOL program.
To define a procedure pointer field you specify USAGE IS PROCEDURE-POINTER
or PROCEDURE-POINTER. You should not code a PIC clause on the definition. You
can assign a value to the procedure-pointer using SET. To pass the procedure
pointer to another program you CALL the program USING the procedure pointer
field.
(CICS/COBOL users may be familiar with pointers, which are used to point to
storage addresses for data items. Although Procedure Pointers follow similar rules
the two types of pointer are different should not be confused.)
3) Watch those compiler options. Some compiler options can result in longer running
times. For example SSR, which checks for subscripts going out of range actually
adds extra code to your program to check subscripts. SSR would be acceptable in a
test environment, but may not be appropriate in the production environment.
4) Sorting. If at all possible avoid doing a sort within a COBOL program. COBOL
sorts are very inefficient. If you must do a sort in a COBOL program, specifying
the FASTSRT compiler option may speed up the sorting process.
5) Numbers.
a) How you define numeric fields can have an impact on performance. If you are
using a field for arithmetic or as a subscript and the field has 8 or fewer digits it is
quite often best to define it as a binary number (COMP-1) that is signed. This is
because binary numbers can be manipulated much faster. If the field has between 8
and 15 digits then it is often best to define it as a Packed decimal number (COMP-
3) with an odd number of digits and signed especially if the number is to be used
with USAGE DISPLAY items. If the number has more than 18 digits then decimal
arithmetic is always used by the compiler. For more information on this check out
the appropriate COBOL Application Programming Guide. Use signed numbers
wherever possible. COBOL does all arithmetic with signed numbers, so if you use
unsigned numbers COBOL has to add code to remove signs.
b) Rounding numbers can often take longer than the calculation so try to avoid
rounding numbers.
6) CALLs to other programs. When calling a subprogram with USING try to specify
as few parameters as possible. Each parameter passed requires an individual BLL
cell to be allocated in the called program and may require additional registers to be
used.
7) PERFORMs. If you do a 'PERFORM paragraph' the compiler may convert this
into up to six machine instructions. This is because the compiler must establish
where it is to jump to and save the address of the instruction to jump back to at
the end of the performed paragraph. PERFORMs with VARYING will require many
more machine instructions. This will probably only be a problem if the code is
executed millions of times. You should weigh up the pros and cons of maintainability
with speed. It might be better to opt for writing the program in Assembler if the
speed of execution is going to be a problem.
EVALUATE WS-X
WHEN 1
ADD 15 TO WS-TOTAL
PERFORM A-100-REPORT
WHEN 2
ADD 16 TO WS-TOTAL
MOVE 'WS-X IS 2' TO WS-DISPLAY
PERFORM A-200-REPORT
WHEN OTHER
PERFORM X-100-ERROR
END-EVALUATE.
This will check the value of the variable WS-X and execute the statements
depending on the value. Note the use of WHEN OTHER this will be executed if
WS-X does not match any of the values, so in the example if WS-X is not equal to 1
or 2 then PERFORM X-100-ERROR will be executed.
Sometimes you will want to have multiple conditions with lots of ANDs and ORs in
an EVALUATE statement as you would in an IF statement. To do this with
EVALUATE requires a slightly different approach. One way is to use EVALUATE
TRUE (or EVALUATE FALSE). for example
EVALUATE TRUE
WHEN WS-X = 1 AND WS-Y = 2
PERFORM X-100-PROCESS1
WHEN WS-X =1 AND WS-Y NOT = 2
PERFORM X-200-PROCESS2
END-EVALUATE.
Here, the whole condition on the WHEN statement is checked and if it is TRUE
then the associated statement(s) are executed.
The second way to do this is using EVALUATE ... ALSO.