1. 導入:なぜ「状態のリセット」が重要なのか
COBOLのサブルーチンを設計する際、呼び出し元のプログラムから「前回の実行結果が残っていて予期せぬ動作をした」というバグに遭遇したことはありませんか?通常、COBOLのプログラムは一度呼び出されると、Working-Storage Sectionの変数は前回の値を保持し続けます。しかし、処理の性質によっては、毎回「まっさらな状態」で開始させたいケースが多々あります。ここで活用すべきなのが「IS INITIAL PROGRAM」属性です。本稿では、この属性の仕組みと、現場で安全に実装するためのポイントを解説します。
2. 基礎知識:内部状態の保持とリセット
COBOLのプログラム(呼び出し先)は、一度実行を終えて呼び出し元に戻っても、メモリ上のデータ領域は解放されず、そのまま保持されるのが一般的です。これを「状態の保持」と呼びます。
一方、「IS INITIAL PROGRAM」属性を付与すると、CALL文で呼び出されるたびに、WORKING-STORAGE SECTIONに定義された変数が、VALUE句で指定された初期値に自動的にリセットされます。これにより、静的変数(static variable)のような振る舞いを防ぎ、再入可能な独立した処理として振る舞うことが可能になります。
3. 実装と解決策
実装は非常にシンプルで、PROGRAM-ID段落で指定するだけです。
構文:PROGRAM-ID. プログラム名 IS INITIAL PROGRAM.
この属性を付与することで、呼び出しのたびに「初期化処理(MOVE SPACES TO …など)」をコーディングする手間が省け、初期化漏れによるデータ汚染のリスクを構造的に排除できます。
4. サンプルプログラム
以下のコードは、累積計算を試みる例ですが、IS INITIAL PROGRAM属性により、呼び出すたびにカウントがリセットされる動作を確認できます。
000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. SUB-CALC IS INITIAL PROGRAM.
000300 この属性により、CALLされるたびにWS-COUNTは0にリセットされる
000400 DATA DIVISION.
000500 WORKING-STORAGE SECTION.
000600 01 WS-COUNT PIC 9(03) VALUE 0.
000700 PROCEDURE DIVISION USING LNK-VAL.
000800 ADD 1 TO WS-COUNT.
000900 MOVE WS-COUNT TO LNK-VAL.
001000 GOBACK.
5. 応用・注意点:現場での判断基準
現場で陥りやすい注意点:
1. パフォーマンスへの影響: 初期化処理が自動で行われるということは、巨大なWORKING-STORAGEを持つプログラムでは、呼び出しのたびにメモリ転送コストが発生します。頻繁に呼び出される基幹処理などでは、パフォーマンスを考慮して「必要な箇所だけ手動リセットする」手法を選ぶのが賢明です。
2. CANCEL文との併用: IS INITIAL PROGRAMを指定しない場合、CANCEL文を使ってプログラムを解放することで初期状態に戻せますが、こちらはオーバーヘッドが大きいです。処理の特性に応じて、「属性によるリセット」か「CANCELによる解放」かを選択してください。
3. 設計指針: 「前回の結果を参照する必要があるか」を基準にしましょう。例えば、ログ出力用プログラムや、毎回入力値のみを変換するようなユーティリティには、この属性を付けることでバグを未然に防ぐことができます。
適切に使い分けることで、より堅牢で保守性の高いプログラムを作成しましょう。

コメント