【実務・中級編】HBOUNDおよびLBOUNDビルトイン関数による境界値取得 – PL/Iの基本構文とデータ制御実践ガイド

メインフレーム開発の現場から:配列の「境界」を制する者は、バッチ改修を制す

若手エンジニアの諸君、今日もVSAMファイルのデバッグや、レガシーバッチの改修でお疲れ様。

PL/Iという言語は、一見するとCOBOLに比べて記述が柔軟で、ポインタ操作まで許容する「自由度の高さ」が魅力だ。しかし、その自由度の裏には、境界値違反(S0C4やS0C5といった悪魔の呼び声)という大きな落とし穴が潜んでいる。

特に、可変長配列や、サブルーチンへ渡された配列のサイズをどう扱うか。今日は、配列の境界判定の要である `HBOUND` と `LBOUND` について、実務の現場で恥をかかないための「作法」を伝授しよう。

なぜ、わざわざHBOUNDを使うのか?

配列を定義する際、`DCL ARR(10) FIXED BIN(31);` のように固定値で書くことは簡単だ。しかし、システムの要件が変われば、この10という数字はたちまち「技術的負債」に変わる。

特に、メインフレームのバッチ処理では、入力レコードの件数や、VSAMの読み込み件数に応じて処理範囲を変えるのが定石だ。配列のサイズをハードコーディングしているソースを見ると、先輩エンジニアとしては「おいおい、次は誰がこの数値を修正するんだ?」と不安になる。

`HBOUND(配列名, 1)` を使えば、その配列の「現在の上限値」をプログラム実行時に動的に取得できる。これにより、配列の定義を変更しても、ロジック側は修正不要(ノーコード)で対応できるというわけだ。

実践:配列境界を考慮した安全なループ処理

以下のコードは、あるVSAMファイルから読み込んだデータを配列に格納し、それを処理する典型的なパターンの抜粋だ。

1
TEST_PROC: PROC OPTIONS(MAIN);

/ 境界値判定を安全に行うための定数定義 /
DCL ARR_SIZE FIXED BIN(31) INIT(100);
DCL WORK_ARR(100) CHAR(80);
DCL I FIXED BIN(31);

/ ONユニットで予期せぬエラーを捕捉する(現場の鉄則) /
ON SUBSCRIPTRANGE BEGIN;
PUT SKIP LIST(‘警告: 配列の境界を超えたアクセスが発生しました’);
STOP;
END;

/ 配列の初期化やVSAM読み込み後の処理を想定 /
/ ここでは簡略化のためループで値をセットする /
DO I = LBOUND(WORK_ARR, 1) TO HBOUND(WORK_ARR, 1);
WORK_ARR(I) = ‘DATA_LINE_’ || TRIM(CHAR(I));
END;

/

  • 【ここがポイント】
  • HBOUND(WORK_ARR, 1) を使用することで、
  • 配列定義変更時もループ回数を自動追従させる

/
DO I = LBOUND(WORK_ARR, 1) TO HBOUND(WORK_ARR, 1);
/ 配列内の各要素に対するビジネスロジック /
CALL PROCESS_DATA(WORK_ARR(I));
END;

PROCESS_DATA: PROC(P_DATA);
DCL P_DATA CHAR(80) PARM;
PUT SKIP LIST(‘処理中: ‘ || P_DATA);
END PROCESS_DATA;

END TEST_PROC;

現場で役立つデバッグのコツと注意点

1. SUBSCRIPTRANGEの活用
`SUBSCRIPTRANGE` オプションを有効にしてコンパイルするのは、開発中の「必須」スキルだ。これを入れていないと、境界を超えたアクセスがあっても警告すら出ずに、メモリ上の隣接領域を破壊して後から原因不明の異常終了を引き起こすことになる。本番リリース時に無効化するとしても、テスト環境では必ずONにしておけ。

2. 多次元配列への対応
`HBOUND(配列名, 2)` とすれば、2次元目の境界も取得できる。複雑なテーブルデータを持つプログラムでは、この第2引数を忘れないように。

3. サブルーチンへの配列渡し
配列を引数として渡す際、呼び出し先で `DCL ARR() CHAR(80);` のように “ を指定して受け取ることが多いだろう。この時、呼び出し先のサブルーチン内で `HBOUND(ARR, 1)` を叩けば、渡された側の配列の大きさを正確に知ることができる。これが「可変長配列」を扱うための最もクリーンな手法だ。

最後に:アーキテクトからのアドバイス

「動くコード」を書くことは誰にでもできる。しかし、メインフレームの長い寿命を考えたとき、本当に価値があるのは「後任者が読みやすく、かつ変更に強いコード」だ。

`HBOUND` や `LBOUND` を使うことは、単なる関数呼び出しではない。「俺はこの配列が将来的にどう変わってもいいように設計しているぞ」という、書き手から読み手への宣言なのだ。

次回のバッチ改修では、固定数値の添字を見つけたら、ぜひこの関数に書き換えてみてほしい。その小さな積み重ねが、君を一人前のメインフレームエンジニアへと押し上げるはずだ。

また何か不明点があれば、いつでも聞きに来るといい。現場からは以上だ。

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