【COBOL学習|実務向け】CALL文の「BY REFERENCE」と「BY CONTENT」で防ぐデータ破壊の罠

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 を選択する習慣をつけましょう。

引数の制御フローを理解することは、大規模なシステムにおける「予測可能なプログラム」を作るための第一歩です。ぜひ、次回のコーディングから意識してみてください。

コメント

タイトルとURLをコピーしました