Showing posts with label INITIAL. Show all posts
Showing posts with label INITIAL. Show all posts

Sunday, 22 September 2013

COBOL Program Termination and Reentry: State and Run Units

A subprogram that executes GOBACK can be called again with its changed Working-Storage still present. Returning control and resetting program state are separate events, which is the central rule behind COBOL program termination and reentry.

COBOL program termination and reentry showing main program subprogram and next-call state
Termination selects the return path; INITIAL, CANCEL, and storage sections determine state on the next call.

Main program, subprogram, and run unit

The first COBOL program in a run unit is the main program. Programs it calls are subprograms; no source declaration permanently marks a separately compiled program as one or the other. The same program can therefore behave differently depending on how it is entered. See COBOL application structure for the calling hierarchy.

Two questions: when a program ends, determine where control must go. When it is called again, determine whether Working-Storage should retain its last-used values or return to its initial values.

Termination statements compared

StatementIn a main programIn a subprogramScope
GOBACKReturns to the caller of the main program, often the operating system.Returns to the statement after the active CALL.Adapts to the program's role.
EXIT PROGRAMNo action.Returns to the calling program without ending the run unit.Called-program return only.
STOP RUNTerminates the run unit and returns to the caller of the main program.Terminates the run unit rather than returning one CALL level.Whole run unit or Language Environment enclave.

GOBACK works in both roles

PROCEDURE DIVISION USING LK-REQUEST LK-RESULT. PERFORM CALCULATE-RESULT GOBACK.

In a called program, GOBACK returns to the instruction after the active CALL. In a main program, it behaves like program termination and returns to the main program's caller. Statements placed after an executed GOBACK are not run, so keep it last in the path.

The dedicated COBOL EXIT and GOBACK guide owns detailed statement syntax. This page concentrates on return scope and reentry state.

EXIT PROGRAM returns from a subprogram

IF LK-REQUEST-VALID = 'N' MOVE 12 TO RETURN-CODE EXIT PROGRAM END-IF

EXIT PROGRAM returns from a called program without ending the run unit. In a main program it has no effect. When a called program reaches its end with no next executable statement, Enterprise COBOL supplies an implicit EXIT PROGRAM, but an explicit termination path is easier to review.

STOP RUN ends the run unit

MOVE 8 TO RETURN-CODE STOP RUN.

STOP RUN closes files in programs belonging to the run unit, terminates the run unit, and returns using the current RETURN-CODE value according to IBM's documented rules. If a subprogram executes STOP RUN, control does not simply return to its immediate caller.

CICS boundary: IBM states that STOP RUN in a CICS environment terminates the entire transaction and its programs. Use the application framework's normal return design; the CICS transaction-flow guide explains task completion.

For statement-specific details, use the separate COBOL STOP RUN page.

Why a returned subprogram can keep old values

IDENTIFICATION DIVISION. PROGRAM-ID. COUNTER1. WORKING-STORAGE SECTION. 01 WS-CALL-COUNT PIC 9(4) VALUE ZERO. LINKAGE SECTION. 01 LK-CALL-COUNT PIC 9(4). PROCEDURE DIVISION USING LK-CALL-COUNT. ADD 1 TO WS-CALL-COUNT MOVE WS-CALL-COUNT TO LK-CALL-COUNT GOBACK.

A normally returned subprogram is usually left in its last-used state. Two calls to COUNTER1 in the same run unit can therefore return 1 and then 2. Return points for performed ranges are reset, but ordinary Working-Storage values can persist.

This is different from Working-Storage versus Local-Storage: Local-Storage is allocated for each invocation and its VALUE clauses are applied on entry.

Three ways to obtain initial state

Use IS INITIAL on PROGRAM-ID

PROGRAM-ID. COUNTER1 IS INITIAL.

The program and its contained programs enter initial state whenever called. Items with VALUE clauses are restored, altered GO TO and PERFORM state is reset, and non-EXTERNAL files are closed as part of initial-state handling.

Compile with the INITIAL option

The compiler option makes the program and its nested programs behave as if IS INITIAL were coded. The focused COBOL INITIAL compiler-option guide covers scope and defaults.

CANCEL an inactive dynamically called program

CALL WS-PROGRAM-NAME USING WS-REQUEST WS-RESULT CANCEL WS-PROGRAM-NAME CALL WS-PROGRAM-NAME USING WS-REQUEST WS-RESULT

A valid CANCEL breaks the program's logical connection so the next call enters initial state. IBM notes that no action is taken when the target has not been dynamically called in the run unit. Do not cancel an active program, a caller above the current program, or a target still active on another thread.

Caller and subprogram example

01 WS-PGM-NAME PIC X(8) VALUE 'COUNTER1'. 01 WS-COUNT PIC 9(4). CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'FIRST=' WS-COUNT CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'SECOND=' WS-COUNT CANCEL WS-PGM-NAME CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'AFTER CANCEL=' WS-COUNT

With the preceding counter subprogram and a dynamic call, typical values are 1, 2, and then 1 after CANCEL. The COBOL CALL statement guide covers USING modes and exception phrases.

Common termination and reentry mistakes

  • Using EXIT PROGRAM in the main program: it performs no termination action there.
  • Using STOP RUN as a subprogram return: it ends the run unit rather than one call level.
  • Assuming Working-Storage resets on every CALL: a returned subprogram is normally in last-used state.
  • Confusing INITIALIZE with IS INITIAL: INITIALIZE changes selected data items; IS INITIAL controls program state on entry.
  • Canceling after every call for performance: dynamic load and initialization work can add overhead; use CANCEL when lifecycle requirements call for it.
  • Ignoring open resources: design file, Db2, and CICS cleanup around the actual termination scope.

Official IBM references

Frequently asked questions

What is the safest COBOL termination statement for both main programs and subprograms?

GOBACK is commonly used because it returns appropriately from either a main program or a called subprogram. The required behavior and site standards still determine the final choice.

Does EXIT PROGRAM end a main COBOL program?

No. EXIT PROGRAM has no effect when executed in a main program. It returns control from a called subprogram without ending the run unit.

Does Working-Storage reset when a COBOL subprogram is called again?

Usually not. A normally returned subprogram is generally reentered in its last-used state. IS INITIAL, the INITIAL compiler option, or a valid CANCEL can cause initial-state entry; LOCAL-STORAGE is allocated afresh for each invocation.

What does STOP RUN do in a COBOL subprogram?

STOP RUN ends the run unit rather than returning only one level to the immediate caller. In CICS it terminates the transaction, so it is not a substitute for a normal subprogram return.

Review rule: choose the return scope first, then document whether a later CALL must see last-used Working-Storage or initial state.

Sunday, 11 August 2013

COBOL INITIAL Compiler Option: Reset Working-Storage

A called COBOL subprogram can remember values in WORKING-STORAGE from the previous call. That is useful for a counter or cached lookup, but it is dangerous when the next call expects a clean start. The INITIAL compiler option changes that behavior by treating programs as if IS INITIAL was coded on PROGRAM-ID.

COBOL INITIAL compiler option diagram showing a CALL, initial state, and VALUE fields
Reset only when needed.

What is the COBOL INITIAL compiler option?

INITIAL causes a program and its nested programs to behave as if the IS INITIAL clause was specified on the PROGRAM-ID paragraph. IBM documents NOINITIAL as the default.

The option is useful when a subprogram must start in the same state each time it is entered. It should not be used as a blanket substitute for clear program initialization logic.

INITIAL vs NOINITIAL

Option Behavior Common fit
INITIAL Treats the program as initially called each time it is entered. Subprograms that must not retain prior call values.
NOINITIAL Leaves normal source behavior in place. Most production programs unless the design needs automatic reset.

PROGRAM-ID IS INITIAL example

The compiler option applies the same idea as coding IS INITIAL in the source. This short example shows the source-level form.

IDENTIFICATION DIVISION.
PROGRAM-ID. ACCTEDIT IS INITIAL.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ERROR-COUNT      PIC 9(04) VALUE ZERO.
01 WS-LAST-FIELD       PIC X(20) VALUE SPACES.

When ACCTEDIT is entered again, the VALUE clauses are used to place those fields back into their starting values.

What happens to WORKING-STORAGE?

IBM documents that WORKING-STORAGE data items normally persist in their last-used state for the duration of the run unit. When a program has INITIAL behavior, WORKING-STORAGE data items are reinitialized each time the program is entered.

There is one important boundary: IBM also notes that INITIAL and IS INITIAL do not affect data items that do not have VALUE clauses. Do not assume every field becomes spaces or zero unless the definition says so.

WORKING-STORAGE vs LOCAL-STORAGE

LOCAL-STORAGE is already allocated for each call or method invocation and freed on return. If a LOCAL-STORAGE item has a VALUE clause, it is initialized on each call. That makes LOCAL-STORAGE a better fit for many temporary fields.

Use INITIAL when the program-level reset behavior is part of the design. Use explicit initialization or LOCAL-STORAGE when only a few fields need fresh values.

When to use INITIAL

  • Use it for a subprogram that must not remember values between calls.
  • Use it when old accumulator, flag, or error fields have caused repeat-call defects.
  • Use it when nested programs also need initial-call behavior.
  • Use source-level IS INITIAL when only one program should behave that way.

When to avoid INITIAL

Avoid INITIAL when retained state is part of the program design. Some subprograms intentionally keep lookup data, counters, or previous-call information in WORKING-STORAGE. Resetting those fields can create wrong results or extra CPU work.

The old version of this post mentioned heavy call overhead in a very small benchmark. Treat that as a warning, not a universal number. Measure your real program if it calls a subprogram many times and the subprogram has large WORKING-STORAGE.

INITIAL, CANCEL, and dynamic CALL

A dynamically called subprogram can be reset after a CANCEL, because it is loaded again on a later call. INITIAL is different: it applies the initial-state behavior each time the program is entered, without depending on a caller issuing CANCEL.

Do not add CANCEL only to clear data if your site avoids it for performance or program-management reasons. Pick the reset method deliberately.

Common mistakes

Expecting fields without VALUE clauses to reset

INITIAL does not make an undefined field clean by magic. Code VALUE clauses or explicit initialization for fields that need known starting values.

Using INITIAL across every compile

A site-wide compiler option can change behavior in many subprograms at once. Review retained-state programs before changing a compile PROC default.

Ignoring nested programs

IBM documents that INITIAL applies to the program and its nested programs. Check nested routines when a reset changes more than expected.

Review checklist

  • Check whether the source already has PROGRAM-ID ... IS INITIAL.
  • Confirm whether the compile listing shows INITIAL or NOINITIAL.
  • List which WORKING-STORAGE fields are expected to retain values.
  • Add VALUE clauses or explicit initialization where fields need known values.
  • Measure call-heavy code before changing reset behavior in a hot path.
  • Retest callers that rely on repeat-call state.

Related Mainframe Forum guides

For nearby topics, read COBOL DYNAM compiler option, COBOL RENT compiler option, COBOL THREAD compiler option, COBOL USAGE clauses, COBOL INITIALIZE statement, and COBOL CALL statement.

External references

IBM documents the INITIAL compiler option, WORKING-STORAGE and LOCAL-STORAGE behavior, and Enterprise COBOL compiler options.

FAQ

What does the COBOL INITIAL compiler option do?

INITIAL makes the program and nested programs behave as if IS INITIAL was coded on PROGRAM-ID.

Is NOINITIAL the default?

Yes. IBM documents NOINITIAL as the default for the Enterprise COBOL INITIAL option.

Does INITIAL reset every WORKING-STORAGE item?

No. INITIAL does not affect data items that do not have VALUE clauses, so fields needing known values still need clear definitions or explicit initialization.

Should INITIAL be used for performance tuning?

No. Use INITIAL for correct reset behavior. If performance is a concern, measure the actual call path and storage size.

New In-feed ads