1. 導入
メインフレーム開発の現場において、サブルーチン間で異なるサイズの配列をやり取りする際、個別にプロシージャを作成するのは非効率です。PL/Iの「アスタリスク()」指定(境界の遅延確定)を活用することで、配列のサイズをハードコーディングすることなく、動的に受け入れる汎用的なモジュールを設計できます。本稿では、この「境界の遅延確定」の仕組みと実装方法を解説します。
2. 基礎知識
PL/Iにおける `DCL ARR(10) FIXED BIN;` といった宣言は、コンパイル時にメモリ領域を確定させます。しかし、サブルーチンの引数として `DCL P_ARR() FIXED BIN;` と記述すると、コンパイラは「この配列のサイズは実行時に引き渡される情報(記述子:Descriptor)を参照せよ」と解釈します。これが「境界の遅延確定」です。内部的には、呼び出し元から渡された制御ブロック(記述子)から配列の開始アドレスや要素数を動的に読み取る仕組みになっています。
3. 実装/解決策
アスタリスク指定を使用する際は、呼び出し先(サブルーチン)側で `HBOUND` 組み込み関数を使用して、実行時の配列サイズ(上限値)を取得するのが定石です。これにより、受け取った配列のサイズが10であっても100であっても、同じロジックで安全にループ処理を行うことが可能です。
4. サンプルプログラム
以下は、任意のサイズの配列を受け取り、その全要素を表示する汎用サブルーチンの例です。
/i
/ メイン処理 /
TEST_PROG: PROC OPTIONS(MAIN);
DCL A(5) FIXED BIN(15) INIT(1, 2, 3, 4, 5);
DCL B(3) FIXED BIN(15) INIT(10, 20, 30);
/ 異なるサイズの配列を同一サブルーチンへ渡す /
CALL PRINT_ARR(A);
CALL PRINT_ARR(B);
END TEST_PROG;
/ 汎用プリントサブルーチン /
PRINT_ARR: PROC(P_ARR);
DCL P_ARR() FIXED BIN(15); / アスタリスクでサイズを遅延確定 /
DCL I FIXED BIN(15);
/ HBOUNDで実行時の配列上限を取得 /
DO I = LBOUND(P_ARR, 1) TO HBOUND(P_ARR, 1);
PUT SKIP LIST(‘要素[‘ || I || ‘]の値: ‘ || P_ARR(I));
END;
END PRINT_ARR;
5. 応用・注意点
注意点1:記述子の不一致
呼び出し元と呼び出し先の宣言で、次元数(DIMENSION)が一致していないと、実行時に「データ例外」や予期せぬメモリアクセスエラーが発生します。アスタリスクはあくまで「境界」を可変にするものであり、次元数自体は呼び出し側と合わせる必要があります。
注意点2:現代言語への移行時の視点
JavaやC#等の言語へ移行する場合、これらは配列自身が `length` プロパティを持っています。PL/Iの `HBOUND` は、移行先では `.length` プロパティへのマッピングとなるため、移行設計時には「PL/Iの記述子から得ていた情報」が、移行先言語のどのプロパティに相当するかを整理しておくことが重要です。
テクニック:
配列の境界チェックを厳密に行いたい場合は、`HBOUND` と `LBOUND` をセットで使用してください。これにより、配列が0始まりか1始まりかに関わらず、柔軟かつ堅牢なコードを維持できます。

コメント