「なぜ変数は初期化されないのか?」――PL/IのAUTOMATICストレージとスタックの深淵
若手エンジニアからよく受ける相談の一つに、「PL/Iの変数が期待した値になっていない」というものがある。特に、複雑なバッチ処理で特定のサブルーチンを繰り返し呼び出した際、前回のゴミが残っているように見える現象だ。
これを「単なるバグ」で片付けてはいけない。これはPL/Iという言語が、極めて効率的かつ合理的にメモリを管理している証左であり、スタック領域(AUTOMATICストレージ)の挙動を理解していないと、大規模システムでは痛い目を見る。
今日は、メインフレームの現場で生き残るために避けて通れない「AUTOMATICストレージの生存戦略」について語ろう。
—
1. AUTOMATICストレージの本質:呼び出しのたびに「生まれ変わる」のか?
PL/Iにおいて、`DECLARE`文でストレージクラスを明示しない場合、デフォルトで`AUTOMATIC`(あるいは`AUTO`)が適用される。これは、その`PROCEDURE`がアクティブな間だけ有効な領域を、システムがスタック上に確保することを意味する。
ここで勘違いしやすいのが、「`PROCEDURE`に入るたびに、メモリがゼロクリアされる」という思い込みだ。
結論から言おう。PL/Iは、パフォーマンスを犠牲にしてまでメモリをゼロクリアするような無駄なことはしない。
`AUTOMATIC`変数は、呼び出し時に単にスタックポインタが移動し、その領域が割り当てられるだけだ。つまり、初期化属性(`INITIAL`)を付けない限り、その領域には「前回の残骸(ガベージ)」がそのまま残っている可能性がある。これを踏まえた設計をしなければ、バッチ処理のデータ不整合は防げない。
—
2. INITIAL属性の「静かなる」タイミング
次に、`INITIAL`属性の挙動だ。多くのプログラマは、`DECLARE`で`INITIAL(0)`と書けば、コンパイル時にバイナリが埋め込まれると誤解しているが、現実はもっと動的だ。
`INITIAL`属性は、その`PROCEDURE`が呼び出されるたびに、スタック上のメモリに対して代入操作(`MOVE`)を実行しているに過ぎない。つまり、`INITIAL`は「宣言」ではなく「実行コード」を含んでいると認識すべきだ。
以下のコードを見てほしい。
1
TEST_PROC: PROCEDURE;
/ 適切に宣言されたAUTOMATIC変数 /
/ INITIAL属性は、呼び出しのたびに実行される /
DCL WORK_COUNTER FIXED BIN(31) AUTO INITIAL(0);
DCL ERR_MSG CHAR(80) AUTO INITIAL(‘ ‘);
/ VSAMやファイル入出力を行う際のバッファ例 /
DCL RECORD_BUF CHAR(1024) AUTO; / 初期化なしは危険! /
/ コンパイラが用意したBUILTIN関数で初期化を安全に行う /
RECORD_BUF = STRING(REPEAT(‘ ‘, 1024));
/ 処理ロジック /
ON ENDFILE(SYSIN) BEGIN;
PUT SKIP LIST(‘データ終了’);
END;
/ 実務では必ずINITIALで初期化するか、明示的にクリアすること /
END TEST_PROC;
—
3. トラブルを未然に防ぐ「現場の鉄則」
大規模なバッチ改修で、私が後輩に厳しく指導しているポイントが3つある。
- 「初期化なし」を許容するな:
`AUTOMATIC`変数は、必ず`INITIAL`属性を付与するか、`PROCEDURE`の冒頭で明示的にクリア(`RECORD_BUF = ‘ ‘` や `UNSPEC(VAR) = ‘0’B` など)する癖をつけろ。デバッグ時に「さっきまでは動いていたのに」という現象の9割は、この初期化漏れによるスタック汚染だ。
- ONユニットのスコープに注意せよ:
`ON`ユニット内でスタック変数を参照する場合、その`PROCEDURE`が既に終了している可能性がある。スタック変数の寿命は「その手続きがアクティブである間」という鉄則を忘れると、予期せぬメモリアドレスを参照する大事故になる。
- パフォーマンスとのトレードオフ:
巨大な構造体(`BASED`ストレージを検討すべきレベルのデータ)を`AUTOMATIC`で宣言すると、呼び出しのたびに初期化処理が走り、CPU時間を浪費する。メモリ効率か、初期化の安全性か。そのバランスを見極めるのがシステムアーキテクトの腕の見せ所だ。
—
最後に:メインフレームの流儀
PL/Iは、現代の言語のように「何でも安全に自動でやってくれる」甘い環境ではない。だが、だからこそメモリをどう使い、どう捨て、どう引き継ぐかを制御できるエンジニアには、極めて強力な武器になる。
スタック上の領域一つ取っても、そこに何が置かれ、いつ消えるのかを想像できること。それが、数百万行のソースコードを読み解き、数十年続く基幹システムを守り抜く唯一の道だ。
次の改修で、`DCL`の行を見たとき、その背後でスタックポインタがどう動いているか、ぜひ一度想像してみてほしい。それがプロのメインフレームエンジニアへの第一歩だ。
