1. 導入:なぜ引数の渡し方が重要なのか
COBOLのシステム開発において、プログラム間連携は避けて通れません。しかし、何気なく記述している「CALL文」の引数の渡し方(BY REFERENCE / BY CONTENT)を意識している技術者は意外と少ないものです。この指定を誤ると、呼び出し先(サブルーチン)で意図せず呼び出し元の変数が書き換えられる「副作用」が発生し、原因の特定が困難なバグを引き起こすことがあります。本記事では、堅牢なプログラムを書くために必須の制御フローを解説します。
2. 基礎知識:引数受け渡しの仕組み
COBOLのCALL文で引数を渡す際、主に2つの方法が存在します。
BY REFERENCE(参照渡し):呼び出し元の変数の「メモリ上のアドレス」を渡します。呼び出し先で値を変更すると、呼び出し元の変数も直接書き換わります。デフォルトの動作であり、効率は良いですが副作用のリスクがあります。
BY CONTENT(値渡し):呼び出し元の変数の「コピー」を作成し、そのコピーのアドレスを渡します。呼び出し先で何をしても、呼び出し元の変数は一切変更されません。データの保護が必要な場合に最適です。
3. 実装・解決策:状況に応じた使い分け
基本方針として「呼び出し先で値を更新する必要がない項目」や「定数的なデータ」を渡す場合は、必ず BY CONTENT を使用するべきです。これにより、意図しないデータ破壊を確実に防ぐことができます。
4. サンプルプログラム
以下のコードは、BY REFERENCEとBY CONTENTの挙動の違いを明示したものです。
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN-PROG.
WORKING-STORAGE SECTION.
01 WS-DATA-REF PIC X(10) VALUE “ABC”.
01 WS-DATA-CON PIC X(10) VALUE “XYZ”.
PROCEDURE DIVISION.
> 参照渡し:SUB内で値が変わるとMAIN側も変わる
CALL “SUB-PROG” USING BY REFERENCE WS-DATA-REF
DISPLAY “参照渡し後: ” WS-DATA-REF > “NEW” と表示される
> 値渡し:SUB内で値が変わってもMAIN側は変わらない
CALL “SUB-PROG” USING BY CONTENT WS-DATA-CON
DISPLAY “値渡し後: ” WS-DATA-CON > “XYZ” のまま維持される
GOBACK.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB-PROG.
LINKAGE SECTION.
01 LS-DATA PIC X(10).
PROCEDURE DIVISION USING LS-DATA.
> 呼び出し先で強制的に書き換える
MOVE “NEW” TO LS-DATA
GOBACK.
5. 応用・注意点:現場でのバグ回避策
現場でよくある失敗として、計算用の作業領域を不用意に BY REFERENCE で渡し、サブルーチン側で初期化漏れや誤った計算結果が書き込まれるケースがあります。
注意点:
・パフォーマンスの考慮:巨大なテーブルを渡す場合、BY CONTENT を使うとコピーのためのメモリ消費と処理時間がかかります。読み取り専用であれば、BY REFERENCE で渡しつつ、呼び出し先で決して変更しないコーディング規約を徹底することも一つの解です。
・保守性の向上:コードレビュー時には「なぜこの引数は BY REFERENCE なのか」を問うことが大切です。安全性を優先するなら、極力 BY CONTENT を選択する習慣をつけましょう。
引数の制御フローを理解することは、大規模なシステムにおける「予測可能なプログラム」を作るための第一歩です。ぜひ、次回のコーディングから意識してみてください。

コメント