導入
大規模な基幹システムにおいて、プログラム間の連携は避けて通れません。動的呼び出し(CALL 変数名)は柔軟性が高い一方、呼び出しのたびにロード処理が発生し、オーバーヘッドが生じます。対して「静的呼び出し」は、コンパイル・リンク時に呼び出し先を確定させるため、実行時の安定性と高速なレスポンスを実現します。本稿では、なぜ静的呼び出しがバッチ処理において「正義」とされるのか、その実装と勘所を解説します。
基礎知識
COBOLにおける「静的呼び出し」とは、CALL命令の引数に「リテラル(文字定数)」を直接指定する手法です。
コンパイラやリンカは、CALL “プログラム名” を見つけると、その呼び出し先をロードモジュールに「直接埋め込み」ます。これにより、OSがプログラムをメモリにロードした瞬間に、呼び出し先のアドレスも解決済みの状態になります。実行時にロードを行う動的呼び出しに対し、静的呼び出しは「あらかじめ結合されている」ため、呼び出し時の負荷が極めて低いのが特徴です。
実装/解決策
静的呼び出しを実装する際は、以下のステップが重要です。
1. CALL文の引数を、変数ではなく “プログラム名” という定数で記述する。
2. リンク時(またはバインド時)に、呼び出し先プログラムのオブジェクトモジュールを明示的に指定する。
3. 呼び出し先プログラムの PROGRAM-ID が、CALL文で指定した名称と一致していることを確認する。
サンプルプログラム
以下は、メインプログラムからサブプログラムを静的に呼び出す例です。
— メインプログラム —
IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
WORKING-STORAGE SECTION.
01 W-DATA PIC X(10) VALUE ‘HELLO’.
PROCEDURE DIVISION.
> 静的呼び出し:プログラム名がリテラルで固定されている
CALL “SUBPROG” USING W-DATA.
STOP RUN.
— サブプログラム —
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
LINKAGE SECTION.
01 L-DATA PIC X(10).
PROCEDURE DIVISION USING L-DATA.
> 受け取った値を表示するだけの処理
DISPLAY “RECEIVED: ” L-DATA.
EXIT PROGRAM.
応用・注意点
現場で静的呼び出しを扱う際の注意点を3つ挙げます。
1. 循環参照の回避
静的呼び出しは強固な結合です。AがBを呼び出し、BがAを呼び出すような循環参照が発生すると、リンクエラーやメモリ不足の原因となります。依存関係を整理した設計を徹底してください。
2. コンパイル単位の管理
呼び出し先を修正した場合、呼び出し元を再コンパイルしなくても済むケースもありますが、インターフェース(USING句の引数)を変更した場合は、必ず両方の再コンパイル・再リンクが必要です。変更の影響範囲を意識したビルド管理が不可欠です。
3. メモリ消費量とのトレードオフ
静的呼び出しは全てのプログラムを一つの巨大なモジュールに詰め込むような構造になりがちです。メモリ制限が厳しい環境では、あまりに多くのプログラムを静的に結合すると、ロードモジュールサイズが肥大化し、実行時にメモリを圧迫することがあります。パフォーマンスとメモリのバランスを見極め、頻繁に呼び出される基幹処理のみを静的呼び出しにするなど、メリハリのある設計を心がけましょう。

コメント