【入門編】CONTROLLED属性によるスタック管理 – PL/Iの基本構文とデータ制御実践ガイド

メインフレームの世界へようこそ。JavaやCOBOLの経験がある方にとって、PL/Iは最初こそ「なんだこの記法は?」と戸惑うかもしれませんが、実は非常に柔軟で、現代の言語にはない「メモリを直接操る快感」を秘めた奥深い言語です。

今日は、PL/Iのメモリ管理の肝である`CONTROLLED`属性について、実務でハマりやすいポイントを交えながら紐解いていきましょう。

1. まるで「引き出し」? `CONTROLLED`属性の正体

JavaやCOBOL(特に静的領域を多用する環境)に慣れていると、変数は「宣言した時点で箱が用意される」ものだと考えがちですよね。しかし、PL/Iの`CONTROLLED`属性は違います。

一言で言えば、「自分でメモリを確保(ALLOCATE)したり、開放(FREE)したりできる『動的な引き出し』」です。

必要なときにだけメモリを確保し、不要になったら捨てる。この自由度の高さがメモリ効率の鍵ですが、同時に「適切に管理しないと痛い目を見る」という側面もあります。

基本のコード例

/i
TEST_PROC: PROCEDURE OPTIONS(MAIN);

/ CONTROLLED属性を付与して宣言 /
/ この時点では、まだこの変数には「実体(中身)」がありません /
DCL MY_BUFFER CHAR(100) CONTROLLED;

/ ここで初めてメモリ領域が割り当てられます /
ALLOCATE MY_BUFFER;
MY_BUFFER = ‘データの格納成功!’;

PUT SKIP LIST(MY_BUFFER);

/ 使い終わったら明示的に開放します /
FREE MY_BUFFER;

END TEST_PROC;

2. 実は「スタック」になっている!再帰呼び出しの魔法

ここからが少し面白いところです。`CONTROLLED`変数は、実はスタック構造になっています。

同じ変数名に対して何度も`ALLOCATE`を繰り返すと、新しいデータが古いデータの上に積み重なっていきます。そして`FREE`を呼ぶと、一番上のデータが消えて、その下にあった以前のデータが再び顔を出します。

再帰呼び出し時の挙動イメージ

再帰関数の中で`ALLOCATE`を行うと、呼び出し階層ごとに別々の「引き出し」が積まれていくわけです。

/i
RECURSIVE_TEST: PROCEDURE(N) RECURSIVE;
DCL N FIXED BIN(15);
DCL TEMP_VAL FIXED BIN(31) CONTROLLED;

/ スタックに新しい値を積む /
ALLOCATE TEMP_VAL;
TEMP_VAL = N 10;

IF N > 1 THEN
CALL RECURSIVE_TEST(N – 1);

PUT SKIP LIST(‘現在の階層 N=’ || N || ‘, TEMP_VAL=’ || TEMP_VAL);

/ スタックから取り出す(開放) /
FREE TEMP_VAL;
END RECURSIVE_TEST;

このように、再帰を抜けるたびに一つ前の`TEMP_VAL`が自動的に復元されます。これは、一時的な計算結果を保持しながら深掘りしていくようなアルゴリズムでは、非常に強力な武器になります。

3. なぜ「怖くない」のか?現場のトラブル回避術

「メモリを自分で管理するなんて、メモリリークが怖い…」と思いますよね。でも安心してください。現場のアーキテクトが教える、トラブルを防ぐためのコツが3つあります。

1. 「ALLOCATEした数だけFREEする」を徹底する

  • 基本中の基本ですが、ループ内で`ALLOCATE`を忘れると悲惨なことになります。必ず対になるように意識しましょう。

2. `ALLOCATION`組み込み関数を活用する

  • その変数が現在いくつのスタックを持っているかは、`ALLOCATION(変数名)`で確認できます。デバッグ時に「あれ?今メモリいくつ確保されてるんだ?」と思ったら、迷わずこれを使ってください。

3. `AUTOMATIC`(デフォルト)との違いを見極める

  • 何も指定しないとPL/Iは`AUTOMATIC`(自動変数)になります。これは手続きに入るときに確保され、出るときに消えます。寿命が短いものは`AUTOMATIC`、プログラム全体や複雑な生存期間管理が必要なものは`CONTROLLED`と使い分けるのがプロの流儀です。

まとめ:PL/Iは「道具」を使いこなす楽しさがある

PL/Iの`CONTROLLED`変数は、メモリという限られた資源を「どう効率よく使うか」という、メインフレーム時代からの知恵が詰まった仕組みです。

最初は少し難解に感じるかもしれませんが、「これはメモリの引き出しを出し入れしているだけ」とイメージしてみてください。スタックの概念が分かれば、再帰処理や大規模バッチのデータハンドリングも恐くありません。

「今の言語の方が便利じゃない?」と思うかもしれません。しかし、大規模基幹システムで数十年にわたって安定稼働しているコードには、こういった「徹底したメモリ制御」の思想が根付いています。

ぜひ、恐れずに`ALLOCATE`して、`FREE`して、PL/Iの奥深さを楽しんでみてくださいね。応援しています!

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