汎用機の鼓動を司る器:PL/IのPROCEDUREブロックと「終わり方」の美学
メインフレームの世界に足を踏み入れて数十年、数多のコードベースを読み解いてきたが、PL/Iほど「書く者の意図」がコンパイラの解釈と密接にリンクする言語は他にない。JavaやC#のモダンな言語構造に慣れたエンジニアが、PL/Iのソースコードを前にして最初に戸惑うのは、その柔軟すぎる(あるいは寛容すぎる)構造だ。
本稿では、PL/Iの実行単位である`PROCEDURE`ブロックと、その終端である`END`ステートメントの厳密な対応関係、そしてそれが基幹システムの安定稼働にどう直結するのかを、現場の視点から掘り下げたい。
—
1. PROCEDUREブロック:エントリーポイントという名の責任
PL/Iプログラムの骨格は、`PROCEDURE`ステートメントで始まり、対応する`END`で閉じる。特に`OPTIONS(MAIN)`を付与されたブロックは、OS(z/OS)から制御を受け取る最初の一点だ。
/i
/ メインルーチンの骨格例 /
MAIN_PROC: PROC OPTIONS(MAIN);
/ 内部変数定義と外部リソース初期化 /
DCL MSG_BUF CHAR(80) VAR;
/ 実行処理ロジック /
MSG_BUF = ‘SYSTEM INITIALIZED.’;
PUT SKIP LIST(MSG_BUF);
/ 終了処理と戻り値の制御 /
RETURN;
END MAIN_PROC; / ラベル名と対にすることで可読性と整合性を担保する /
ここで重要なのは、`END`ステートメントに必ずブロック名(ラベル)を付与する癖をつけることだ。複雑なネスト構造になった際、`END`がどの`PROCEDURE`を閉じているのか不明瞭なコードは、保守フェーズにおけるアベンドの温床となる。
—
2. ポインタと動的メモリ操作:自由と引き換えの「禁断の果実」
PL/Iの真骨頂は、`BASED`変数と`POINTER`型を用いたメモリ制御にある。Javaのガベージコレクションに守られた環境とは異なり、ここでは開発者がメモリの生殺与奪の権を握っている。
/i
/ 動的メモリ確保のパターン /
DCL 1 MY_REC BASED(P_REC),
2 DATA_LEN FIXED BIN(15),
2 DATA_VAL CHAR(100);
DCL P_REC POINTER;
/ ストレージの割り当て /
ALLOCATE MY_REC;
/ ここでP_RECに不正なアドレスが入るとS0C4アベンドに直結する /
/ 移行時にはこのALLOCATEとFREEの対が、ライフサイクル全体で正しく維持されているか精査が必要 /
FREE MY_REC;
マイグレーション時に最も苦労するのは、この動的メモリの生存期間(Scope)と、CICS環境でのストレージリークだ。現代の環境へ移行する際、PL/Iの`BASED`変数をそのままクラス構造に写し替えるのは危険だ。スタック管理とヒープ管理の境界をどこに置くか、システムアーキテクトとしての手腕が問われる。
—
3. バグの温床:パックデシマルの内部符号と最適化の罠
基幹システムにおいて、`FIXED DEC(15,0)`のようなパックデシマル(COMP-3)は銀行の残高計算などで不可欠だ。しかし、コンパイラの最適化オプション(`OPT(2)`や`OPT(3)`)を適用した際、稀に内部符号(`X’C’`や`X’D’`)の判定が、期待した挙動と異なる場合がある。
特に、DB2のSQL実行結果をFETCHする際、定義と実際のデータが一致していないと、コンパイラが「あり得ない最適化」を施し、予期せぬ論理エラーを引き起こすことがある。
- 対策: 外部インターフェースとなるデータ定義には、`UNALIGNED`属性を適切に付与し、メモリ上のビットアライメントを明示的に制御せよ。
- ダンプ解析: `CEE3DMP`によるダンプを読む際、ポインタの指す先がパックデシマルか否かを即座に見抜く目が、レガシーエンジニアの矜持である。
—
4. 移行設計へのアドバイス:終わりの始まり
JavaやC#への移行を検討している読者に伝えたいことがある。それは、「PL/Iの`PROCEDURE`を単なるメソッド変換で終わらせてはならない」ということだ。
`PROCEDURE`の背後には、`ON-UNIT`(例外ハンドラ)によるエラー処理や、`STATIC`変数による静的な状態保持が隠されている。これらを現代の言語で再現する場合、例外処理の粒度をどう設計するか、シングルトンパターンで状態をどう管理するか。その設計思想こそが、マイグレーションの成否を決める。
結び
`END`ステートメントにラベルを打つという些細な規律は、実はシステム全体を守るための最初の防波堤だ。基幹システムのコードは、単なる命令の羅列ではなく、数十年積み重ねられた業務ロジックの結晶である。
次回のメンテナンスで、あなたが`PROCEDURE`の終端にラベルを打つとき、それはただの記述ではない。そのシステムが安定して動き続けるための、アーキテクトとしての意思表示であることを忘れないでほしい。
—
本稿が、貴殿のレガシー移行プロジェクトにおける技術的な羅針盤となれば幸いである。

コメント