1. 導入:なぜGIVING句なのか
長年COBOLの現場にいると、サブルーチンの呼び出し後に「正常に終わったのか」「エラーならどんな理由か」を判定するために、共通域(通信領域)をいちいち参照するコーディングに辟易することがあります。例外オブジェクト(TRY-CATCH)は強力ですが、オーバーヘッドが大きく、パフォーマンスがシビアな基幹系バッチには不向きな場面も多いものです。そこで活用したいのが、COBOL 2002から標準化された「GIVING句」によるステータス取得です。この手法を使えば、手続きの成否を簡潔に、かつ低コストで判定できるようになります。
2. 基礎知識:GIVING句と戻り値の仕組み
COBOLのCALL文において、GIVING句は呼び出されたプログラム(あるいは外部関数)が終了する際に返す「戻り値」を直接受け取るための指定です。
従来のCOBOLでは、ステータスは呼び出し側と呼び出され側の双方で定義した「共有領域」に書き込む手法が一般的でした。しかし、GIVING句を利用することで、C言語などの他言語との連携時と同様に、レジスタやスタックを経由して直接数値を受け取ることが可能になります。これにより、グローバル変数の競合や、領域の定義漏れによるバグのリスクを大幅に低減できます。
3. 実装と解決策
実装の手順は極めてシンプルです。呼び出し側(CALL側)で戻り値を受け取るための数値項目を定義し、CALL文の末尾に「GIVING 一意名」を記述するだけです。
重要なのは、呼び出される側のプログラム(副プログラム)でも、EXIT PROGRAM 文または GOBACK 文に RETURNING 句を指定して値を返すように構成することです。これにより、呼び出し側と呼び出され側で厳密な値の受け渡しが可能になります。
4. サンプルプログラム
以下のコードは、呼び出し側が副プログラムのステータスをGIVING句で受け取る実用例です。
[CALL側の実装]
WORKING-STORAGE SECTION.
01 WS-STATUS PIC S9(9) COMP-5. > 戻り値受取用
PROCEDURE DIVISION.
> SUB-PROGRAMを呼び出し、ステータスをWS-STATUSに格納
CALL “SUB-PROGRAM” GIVING WS-STATUS.
> ステータス判定(0は正常終了の例)
IF WS-STATUS = 0
DISPLAY “正常終了しました。”
ELSE
DISPLAY “異常終了: コード = ” WS-STATUS
END-IF.
GOBACK.
[副プログラム側の実装]
PROCEDURE DIVISION RETURNING RET-VAL.
01 RET-VAL PIC S9(9) COMP-5.
> 処理ロジック
IF 処理失敗
MOVE 8 TO RET-VAL > エラーコードを返却
ELSE
MOVE 0 TO RET-VAL > 正常終了
END-IF.
GOBACK.
5. 応用・注意点
現場での運用において、いくつか注意すべき点があります。
まず、ステータスコードの定義を共通化することです。プロジェクト内で「0=正常」「8=ファイルなし」「16=致命的エラー」といったコード表を策定し、COPY句で定義ファイルを共通化してください。コードがマジックナンバー化すると、メンテナンス性が著しく低下します。
また、GIVING句の戻り値は多くの場合「整数型(COMP-5等)」で扱われます。C言語等との連携を考慮するなら、符号付きの4バイト整数(PIC S9(9) COMP-5)に統一しておくと、プラットフォーム間の差異を吸収しやすく、移植性の高いコードになります。
例外オブジェクトに頼りすぎず、こうした軽量なステータス判定を使い分けることこそ、モダンCOBOLを操るベテランの嗜みと言えるでしょう。

コメント