【PL/I深層解説】AUTOMATICとSTATICの「寿命」を見極めれば、バグは激減する
メインフレームの保守現場で、なぜか「特定のバッチジョブでたまに値が化ける」「再実行すると正常に動く」という不可解な事象に遭遇したことはないだろうか。その原因の多くは、メモリ管理、特に`AUTOMATIC`と`STATIC`の生存期間(Storage Duration)に対する理解不足にある。
今日は、PL/Iにおけるストレージ属性の基本を再確認し、なぜそれが再入可能性(Reentrancy)やマルチタスク環境において極めて重要なのか、現場の視点で深掘りする。
—
1. AUTOMATICとSTATIC:メモリの「宿命」
PL/Iにおいて、変数の属性を明示しない場合、デフォルトで`AUTOMATIC`が適用されることが多い(※環境によるが、明示するのがプロの作法だ)。
- AUTOMATIC(スタック領域)
- 寿命: プロシージャが呼び出された瞬間に生成され、リターン時に即座に破棄される。
- 特徴: プロシージャ呼び出しごとにメモリが再確保されるため、「再入可能(Reentrant)」である。CICSのトランザクションや、バッチ内の再帰呼び出しにおいて必須の属性だ。
- STATIC(静的領域)
- 寿命: プログラムのロードから終了まで生存し続ける。
- 特徴: 前回の処理で書き込んだ値が、次回の呼び出し時にもそのまま保持される。一見便利そうだが、これが「意図しない変数の保持」という厄介なバグの温床となる。
—
2. 実践コード:STATICの「呪い」とAUTOMATICの恩恵
以下のコード例を見てほしい。カウンターをインクリメントするだけの単純なロジックだが、STATICを使うとマルチ呼び出しで破綻する。
/i
DEMO_PROC: PACKAGE;
/ STATICはロード時に一度だけ初期化される /
DCL STATIC_CNT FIXED BIN(31) STATIC INIT(0);
/ 業務処理プロシージャ /
PROCESS_DATA: PROC(INPUT_VAL) OPTIONS(MAIN);
DCL INPUT_VAL FIXED BIN(31);
/ AUTOMATICは呼び出しごとに0クリアされる(再入可能) /
DCL AUTO_SUM FIXED BIN(31) AUTOMATIC INIT(0);
STATIC_CNT = STATIC_CNT + 1;
AUTO_SUM = INPUT_VAL + 100;
PUT SKIP LIST(‘STATICカウント:’, STATIC_CNT);
PUT SKIP LIST(‘今回の計算値:’, AUTO_SUM);
/
注意:
STATIC_CNTはプログラムが終了するまでメモリに残り続ける。
別のジョブステップやサブルーチンから再利用された際に、
前回の値が残っていると致命的なバグとなる。
/
END PROCESS_DATA;
END DEMO_PROC;
—
3. なぜ「再入可能性」が重要なのか
現代のメインフレーム運用、特に高負荷なバッチ処理やCICS環境では、同じプログラムが複数のタスクから同時に(あるいは順次)呼び出されることが前提だ。
もし、あなたが`STATIC`属性を「初期化の手間を省くため」という安易な理由で多用しているなら、今すぐ見直すべきだ。`STATIC`な変数は、メモリ上で一つの場所を共有する。つまり、「Aというデータの処理中に、誰かが勝手に値を書き換えてしまう」という並行処理の競合リスクが常に付きまとう。
現場で役立つデバッグの知見
もし不可解なデータの変遷に悩んだら、以下のチェックリストを試してほしい。
1. 初期化漏れを疑う: `AUTOMATIC`変数に`INIT`を忘れていないか?(PL/Iでは未初期化の場合、ゴミ値が入る)。
2. STATICの多用を排除する: `STATIC`を使っている変数を`AUTOMATIC`に書き換え、プログラムが正常に動作するか試す。これでバグが消えるなら、メモリの生存期間の混同が原因だ。
3. ONユニットとの兼ね合い: `ON ERROR`や`ON ENDFILE`などのONユニット内で、特定の変数(`STATIC`など)を参照・更新している場合、予期せぬタイミングで値が書き換わることがある。ONユニット内では、可能な限りそのスコープ内の変数のみを操作するよう設計せよ。
—
4. 最後に:スペシャリストへの道
PL/Iは古い言語だと言われることもあるが、そのメモリ制御の厳格さは、現代のメモリ管理が抽象化されすぎてブラックボックス化している言語よりも遥かに理に適っている。
`AUTOMATIC`を基本とし、どうしてもプログラム全体で状態を保持しなければならない場合のみ`STATIC`を検討する。この「原則」を守るだけで、あなたの書くコードは驚くほど安定し、後輩からの「なぜか動かないんです」という相談も激減するはずだ。
システム移行や大規模改修の現場では、コードの「意図」を読む力が問われる。メモリがいつ生まれ、いつ消えるのか。その呼吸を感じ取れるようになって初めて、真のシステムアーキテクトと言えるだろう。
次回のブログでは、`STORAGE`クラスとポインタを用いたメモリ管理の深淵について解説する予定だ。準備はいいか?コードは裏切らない。ただ、書き手側の無知を暴くだけなのだ。
