【実務・中級編】CONTROLLEDストレージクラスによるスタック管理とALLOCATE/FREE – PL/Iの基本構文とデータ制御実践ガイド

現場のエンジニアへ告ぐ:PL/IのCONTROLLED属性を「なんとなく」使うな

メインフレームの現場で何十年も生き残っているPL/Iだが、その柔軟性が災いしてか、今なお「メモリリーク」や「意図しないデータ破壊」の温床となっている箇所がある。特に`CONTROLLED`属性は、使いこなせば強力な武器になるが、スタック管理の仕組みを理解せずに書けば、バッチが深夜の運用で突然異常終了(ABEND)する原因になりかねない。

今日は、CONTROLLEDストレージのスタック構造と、実務で絶対に守るべき鉄則を共有しよう。

CONTROLLED属性の本質:スタック管理の正体

通常、PL/Iの変数は`AUTOMATIC`(自動スタック)として確保されるが、`CONTROLLED`を指定すると、プログラマがメモリの寿命を完全に制御できる。

ここで重要なのは、`ALLOCATE`を実行するたびに、その変数は「スタックの頂上」に積み上げられるということだ。既存の同名変数は隠蔽され、`FREE`を実行すると、現在スタックの頂上にあるものが破棄され、その下の層(一つ前の世代)が再び有効になる。

この挙動を「世代管理」として活用できるかどうかが、ベテランと初心者の分かれ目だ。

実践的コード例:動的配列のスタック管理

以下の例は、VSAMファイルから読み取ったレコードを、可変長のスタック構造で処理する際の定石だ。

1
TEST_STACK: PROCEDURE OPTIONS(MAIN);

/ CONTROLLED属性で宣言された構造体 /
DCL 1 WORK_REC CONTROLLED,
2 KEY_ID CHAR(8),
2 DATA_VAL FIXED BIN(31);

/ VSAMファイル定義(簡略化) /
DCL VSAM_FILE FILE RECORD INPUT;

/ エラーハンドリング:ONユニットの制御フロー /
ON ENDFILE(VSAM_FILE) BEGIN;
/ スタックが空になるまで解放する安全なループ /
DO WHILE(ALLOCATION(WORK_REC) > 0);
FREE WORK_REC;
END;
STOP;
END;

OPEN FILE(VSAM_FILE);

DO FOREVER;
/ スタックに新しい世代を追加 /
ALLOCATE WORK_REC;

READ FILE(VSAM_FILE) INTO(WORK_REC);

/

  • ここでALLOCATIONビルトイン関数を使い、
  • 現在のスタック深さをチェックするのはデバッグの基本だ

/
PUT SKIP LIST(‘現在のスタック深度:’ || ALLOCATION(WORK_REC));

/

  • 処理ロジック…
  • もしここでFREEを忘れると、ループのたびに領域が確保され、
  • いずれGETMAINエラーでシステムごと落とすことになる

/
FREE WORK_REC;
END;

END TEST_STACK;

現場で陥る「スタック・トラップ」の回避策

実務において、`CONTROLLED`を扱う際に必ず覚えておくべきポイントは以下の3点だ。

1. ALLOCATIONビルトイン関数の活用

「今、何層積み上がっているか?」を把握することは、バグ調査の第一歩だ。`ALLOCATION(変数名)`は、現在のスタックの深さを返してくれる。`FREE`をしたはずなのにメモリエラーが出る場合、まずはログにこの値を吐き出して、意図せぬネストが発生していないか確認しろ。

2. FREEの確実な実行

例外処理(ONユニット)の中に`FREE`を書くのは非常に重要だが、もっと良いのは「構造化」だ。可能な限り`ALLOCATE`と`FREE`を同一プロシージャ内のスコープに収めろ。呼び出し先で`ALLOCATE`し、戻り側で`FREE`するような設計は、メンテナンスの難易度を跳ね上げるだけだ。

3. 世代管理とポインタの意識

`CONTROLLED`変数は、内部的にはポインタのチェインで管理されている。誤って同じポインタを二重に操作したり、解放済みの世代を参照したりするコードは、メインフレーム特有の「データの一貫性欠如(サイレントデータ破損)」を引き起こす。これが一番恐ろしい。デバッグ時は、必ずコンパイラオプションで適切なストレージ保護(`CHECK`や`SUBSCRIPTRANGE`など)を有効にしてテストを行え。

最後に:スペシャリストへの道

PL/Iの強みは、開発者がハードウェアの限界に近い領域まで直接制御できることにある。`CONTROLLED`属性によるスタック管理は、現代の言語にはない、メインフレームエンジニアだけの特権だ。

「とりあえず動けばいい」ではなく、「メモリの世代が今どこにあるか」を頭の中で可視化できる人間になれ。そうすれば、複雑なバッチ改修でも、誰よりも早く問題の核心に辿り着けるはずだ。

もし大規模マイグレーションで古いコードの解析に詰まったら、まずは`ALLOCATE`の回数と`FREE`のペアが正確か、ログを辿ることから始めることだ。それが、トラブルシュートの近道だ。健闘を祈る。

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