【PL/I学習|初心者向け】メインフレームの知恵袋:ADDR関数を使った「参照渡し」のシミュレーション術

1. 導入:なぜ「番地」を渡す必要があるのか?

メインフレームのPL/I開発において、サブルーチンへデータを渡す際、通常は「値渡し」に近い形式をとります。しかし、外部のC言語プログラムや、古いF77(FORTRAN)との連携、あるいはメモリ効率を考慮した大規模データの操作を行う際、「データのコピー」は避けたい課題となります。ここで登場するのが「ADDR関数」を使った参照渡し(ポインタ渡し)のテクニックです。これを使えば、メモリ上の特定の場所を直接指し示すことで、効率的かつ柔軟なデータ操作が可能になります。

2. 基礎知識:ポインタとBASED属性

この手法を理解するために、2つの重要キーワードを覚えましょう。
・ADDR関数:指定した変数がメモリ上のどこに存在するか(アドレス=番地)を返します。
・BASED属性:変数を定義する際、その変数が「どこか特定の番地にあるもの」であることを明示します。通常の変数とは異なり、メモリの場所を自分で指定しない限り、実体を持たない「型定義」のような存在です。
これらを組み合わせることで、呼び出し元と呼び出し先で同じメモリ領域を共有することができます。

3. 実装と解決策:ポインタの受け渡し手順

実装の流れは以下の通りです。
1. 呼び出し元で、ADDR関数を使って変数のアドレスを渡す。
2. 呼び出し先で、受け取り側をPOINTER型として定義する。
3. 受け取ったポインタを、BASED属性を持つ変数に「セット」して操作する。
これにより、呼び出し先での変更が、呼び出し元の変数にそのまま反映されます。

4. サンプルプログラム

以下のコードは、メインプログラムから変数のアドレスを渡し、サブルーチン側でその値を書き換える例です。

/ — メインプログラム — /
DCL MY_VAL FIXED BIN(31) INIT(100);
DCL ADDR BUILTIN;

/ サブルーチンを呼び出す際、値ではなくアドレスを渡す /
CALL SUB_PROC(ADDR(MY_VAL));

PUT SKIP LIST(‘変更後の値:’, MY_VAL); / 結果は200になる /

/ — サブルーチン — /
SUB_PROC: PROC(P_IN);
DCL P_IN POINTER; / アドレスを受け取るポインタ変数 /

/ 渡されたアドレスを元に操作するためのBASED変数 /
DCL B_VAL FIXED BIN(31) BASED(P_IN);

/ 直接メモリを書き換える /
B_VAL = 200;
END SUB_PROC;

5. 応用・注意点:現場での運用Tips

この手法は非常に強力ですが、注意点も存在します。
・バグの温床に注意:ポインタを誤ったアドレスに向けると、意図しないメモリ領域を破壊する恐れがあります。BASED変数を操作する際は、必ずポインタが正しい領域を指しているか確認してください。
・現代言語への移行:将来的にJava等へ移行する場合、この「ADDR」の概念は「オブジェクト参照」や、Javaであれば「AtomicReference」のようなラッパークラスに置き換える必要があります。直接的なメモリ操作は移行時に修正コストが高くなるため、この手法を使う際は、どの範囲でこの「ポインタ操作」を行っているのかを明確にドキュメント化しておくことが、保守性を保つ鍵となります。

コメント

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