PL/Iの「配列境界チェック」を攻略する!――見えない地雷を可視化するテクニック
こんにちは。メインフレームの世界へようこそ。
普段、JavaやCOBOLに親しんでいる方にとって、PL/Iという言語はどこか「古めかしく、難解なルールが多そう」という印象があるかもしれません。実際、PL/Iは非常に強力で自由度が高い分、使い方を一歩間違えると「なぜか動くけれど、どこで壊れたか分からない」という深淵に足を踏み入れてしまうことがあります。
今日は、その代表格である「配列の添字範囲外アクセス(SUBSCRIPTRANGE)」について、現場の知恵を交えて紐解いていきましょう。
—
1. なぜPL/Iで「添字」が怖いのか?
Javaなら `ArrayIndexOutOfBoundsException` が出て親切に教えてくれますよね。でも、PL/Iは歴史的な背景もあり、デフォルトでは「境界チェックを行わない」設定になっていることが多いんです。
これは「実行速度を極限まで速くしたい」という当時のエンジニアたちの矜持の表れでもあるのですが、結果として、隣のメモリ領域を平気で書き換えてしまう「サイレント・バグ」を招くことがあります。
住所の例え話
配列を「マンションの部屋」だと想像してください。
- Java: 101号室から105号室しかないマンションで106号室に入ろうとすると、管理人が猛烈な勢いで止めてくれます。
- PL/I: 106号室のドアを開けても、壁を突き抜けて隣のビル(他の変数領域)に侵入して、勝手に壁紙を塗り替えてしまうことがあります。そして、プログラムは何事もなかったかのように動き続けます。
これが、メインフレームのデバッグで最も恐ろしい瞬間です。
—
2. 魔法の呪文「ON SUBSCRIPTRANGE」
この恐怖を未然に防ぐために、私たちは`ON`ユニットという強力な武器を使います。これを使うと、配列の境界を超えた瞬間に「おい、そこは入っちゃダメだ!」とエラーをキャッチし、ログを吐き出させることができます。
さっそく、コードを見てみましょう。
1
/ PACKAGEはプログラムの大きな区切り。ここから始まります /
TEST_PROG: PACKAGE;
/ メイン処理の入り口 /
MAIN_PROC: PROCEDURE OPTIONS(MAIN);
/ 1から5までしか部屋がないマンション /
DCL ARR(5) FIXED BIN(31) INITIAL((5)0);
DCL I FIXED BIN(31);
/ ここが重要!境界チェックを有効にするための魔法 /
ON SUBSCRIPTRANGE
BEGIN;
PUT SKIP LIST(‘警告: 配列の範囲外へアクセスしました!’);
/ 必要ならここで異常終了させることも可能です /
SIGNAL ERROR;
END;
/ あえて範囲外(6番目)にアクセスしてみる /
I = 6;
ARR(I) = 999;
PUT SKIP LIST(‘無事に処理が完了しました(と見せかけているだけ)’);
END MAIN_PROC;
END TEST_PROG;
—
3. 実務で役立つ「コンパイルオプション」の裏技
コード内に`ON`ユニットを書くのも大切ですが、現場のプロはコンパイル時にもう一工夫加えます。
コンパイルオプションに `SUBSCRIPTRANGE` を付与するのです。
これを付けると、コンパイラが「お前、配列アクセスする箇所には必ずチェックコードを埋め込むからな!」と強制的にガードを固めてくれます。
- 開発環境(テスト時): 必ず `SUBSCRIPTRANGE` を指定しましょう。少し速度は落ちますが、バグを早期発見できるメリットは計り知れません。
- 本番環境: 速度が命のバッチでは外すこともありますが、現代のメインフレームの性能であれば、基本的には「付けっぱなし」にするのがシステムアーキテクトとしての推奨です。
—
4. 最後に:怖がらなくて大丈夫です
PL/Iの宣言や記述に、最初は戸惑うかもしれません。「なぜ `DCL` と書くのか?」「`FIXED BIN(31)` とは何だ?」など、細かい疑問は尽きないでしょう。
でも大丈夫です。これらはすべて、「限られたリソースをどう効率的に管理するか」という、メインフレームが歩んできた歴史的な知恵の結晶です。
もしバグに遭遇したら、まずは `ON SUBSCRIPTRANGE` を試してみてください。それだけで、プログラムが語りかけてくる「悲鳴」が聞こえるはずです。
何か分からないことがあれば、いつでも聞いてくださいね。一緒にメインフレームの世界を、一つずつ攻略していきましょう。あなたの基幹システムが、今日も安全に稼働することを祈っています。
