【実務・中級編】STATIC属性による静的メモリ確保 – PL/Iの基本構文とデータ制御実践ガイド

PL/Iの「STATIC」と再入可能性:レガシーシステムの深淵を歩くエンジニアへ

諸君、お疲れ様。今日も今日とてJCLの海を泳ぎ、VSAMの不整合と戦っていることだろう。

PL/Iという言語は、一見すると「古臭い」と揶揄されがちだが、その仕様の懐の深さは、現代の言語が忘れてしまったメモリ管理の哲学を色濃く残している。特に、今日語るSTATIC属性は、バッチ処理の心臓部を支える一方で、マルチスレッド環境や複雑な再帰呼出しにおいて、往々にして「なぜ値が化けるのか?」という悪夢のトリガーとなる。

今日は、現場の保守で死なないための「静的メモリ」の作法を共有しよう。

1. STATIC属性の本質:なぜ「そこ」にあるのか

PL/Iにおいて、`STATIC`属性を持つ変数は、プログラムの実行開始から終了まで、ロードモジュール内の静的領域に居座り続ける。

自動変数(AUTOMATIC)がプロシージャの起動のたびにスタック上に生成され、終了と共に消滅するのに対し、`STATIC`は「前回の呼び出し時の値」を保持する。これを利用して、処理件数のカウントや、初回起動時の定数読み込み判定(イニシャライズ・フラグ)によく使われるわけだ。

しかし、ここで一つ重要なことを忘れてはならない。PL/Iには「予約語」が存在しない。
`IF`や`THEN`さえも、文脈次第で変数名にできてしまう。この仕様は強力だが、`STATIC`と命名した変数を誤って定義したりすると、デバッガを片手に徹夜することになる。命名規約はプロジェクトの防波堤だ。必ずプレフィックスを付ける癖をつけろ。

2. 実践:VSAM制御とSTATICの正しい付き合い方

例えば、VSAMファイルからレコードを読み込み、ある特定のバッファを保持し続けたい場合、以下のように書くのが定石だ。

1
/ —————————————————————– /
/ STATIC変数を用いた初回読み込み判定とVSAMレコード保持の例 /
/ —————————————————————– /
PROCESS OPTIONS(MAIN);

TEST_PGM: PROC OPTIONS(MAIN);

/ STATIC変数はプログラム生存期間中、値を保持する /
DCL G_INIT_FLG BIT(1) STATIC INIT(‘0’B);
DCL G_REC_BUF CHAR(100) STATIC;

DCL VSAM_FILE FILE RECORD INPUT;

ON ENDFILE(VSAM_FILE) BEGIN;
PUT SKIP LIST(‘EOF検出’);
STOP;
END;

IF ¬G_INIT_FLG THEN DO;
/ 初回のみ実行される初期化処理 /
OPEN FILE(VSAM_FILE);
G_INIT_FLG = ‘1’B;
END;

READ FILE(VSAM_FILE) INTO(G_REC_BUF);

/ BUILTIN関数による文字列操作の例 /
IF SUBSTR(G_REC_BUF, 1, 5) = ‘DATA1’ THEN DO;
/ 何らかのロジック /
END;

END TEST_PGM;

このコードのポイントは、`G_INIT_FLG`を`STATIC`にすることで、複数回のREAD処理を通しても状態が壊れないことだ。だが、もしこのプロシージャが再帰呼び出しされたり、あるいはCICS環境でマルチスレッド的に再入(Reentrant)されるような設計の場合、`STATIC`は「地雷」に変わる。

3. 「再入可能性(Reentrancy)」という名の壁

諸君が担当しているのが、もし大規模なオンラインバッチや、Javaから呼び出されるJNI経由のPL/Iプログラムなら注意が必要だ。

`STATIC`変数は「モジュール単位で共有」される。つまり、Aというトランザクションが`G_REC_BUF`を書き換えている最中に、Bというトランザクションが割り込んできたらどうなるか。当然、値は上書きされ、結果は予測不能な壊滅的データ不整合を引き起こす。

トラブルを防ぐための鉄則:

1. 再入可能(Reentrant)が必要なモジュールでは、`STATIC`を極力使わない。

  • 代わりに、呼び出し元から引数(ADDR関数でポインタを渡すなど)でワークエリアを受け取る設計にする。

2. どうしても使うなら、`EXTERNAL STATIC`には細心の注意を払う。

  • リンクエディット時に他のモジュールから参照されるリスクがある。`CONTROLLED`属性によるメモリ管理の方が、複雑だが安全な場合が多い。

3. ONユニットでの状態管理には使わない。

  • `ON`ユニット内で`STATIC`変数を操作すると、異常終了からのリカバリ処理(RETRYなど)において、予期せぬ副作用を生むことが多い。

最後に:ベテランからのアドバイス

「PL/Iは古い」と言う若手ほど、メモリ管理の基本的な概念(スコープとライフサイクル)で躓く。`STATIC`は便利だが、それは「プログラムの寿命まで全責任を持つ」という契約のようなものだ。

もし改修現場で、`STATIC`変数がスパゲッティのように絡み合っているソースを見つけたら、まずはその変数が「どこで初期化され、どこで破壊されているか」をクロスリファレンスで徹底的に追え。

メインフレームのコードは正直だ。設計者が楽をしようとして書いた`STATIC`は、数十年後の君たちに牙を剥く。堅牢なシステムを構築したければ、常に「この変数は誰と共有されているのか?」を自分に問い続けろ。

健闘を祈る。また何かあればいつでも聞きに来てくれ。

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