PL/Iの「メモリの深淵」を覗く:LENGTHとSTG関数でデバッグを味方につける
こんにちは。長年メインフレームの保守・運用、そして数々のマイグレーションプロジェクトを渡り歩いてきたシステムアーキテクトです。
「PL/I? なんだか古めかしくて難しそう……」と身構えていませんか? 大丈夫です。JavaやCOBOLを経験された皆さんなら、PL/Iの「自由度の高さ」は、むしろ心強い武器になります。今回は、PL/Iのプログラムをデバッグする際に、まるで「レントゲン撮影」のように内部構造を可視化してくれる強力な武器、`LENGTH`関数と`STG`(Storage)関数について紐解いていきましょう。
—
なぜPL/Iのメモリ管理を知る必要があるのか?
COBOLであればレコード定義(FD)がガチガチに決まっていますが、PL/Iは違います。`VARYING`属性を使った可変長文字列や、ポインタを使った動的なメモリ割り当てが日常茶飯事だからです。
「あれ、今この変数には何バイト入っているんだ?」
「構造体の中身、実際にメモリ上でどう並んでいる?」
こうした疑問を解決しないまま突き進むと、バッチ処理で突然の異常終了(ABEND)に泣くことになります。そんなとき、この2つの関数があなたの命綱になります。
—
1. LENGTH関数:文字列の「今の姿」を測る
`LENGTH`関数は、文字列の長さを返します。ここでのポイントは、「宣言時の最大長」ではなく「現在保持している有効長」を返してくれるという点です。
特に`VARYING`属性の変数を使う場合、`LENGTH`は非常に頼りになります。
1
/ 宣言:最大100バイトだが、中身は可変 /
DCL MY_NAME CHAR(100) VARYING;
MY_NAME = ‘IBM_MAINFRAME’;
/ LENGTHで現在の長さを取得 /
PUT SKIP LIST(‘現在の文字列長は: ‘ || LENGTH(MY_NAME));
/ 結果は 13 と出力されるはずです。便利ですよね? /
もしこれが`VARYING`なしの`CHAR(100)`だと、常に100が返ってきます。ここを混同しないのが、PL/I使いへの第一歩です。
—
2. STG関数:メモリの「素顔」を覗く
次に紹介する`STG`(Storage)関数は、少し上級者向けですが、デバッグの最終兵器です。これは、指定した変数や構造体が、メモリ上のどこからどこまでを占有しているのか(アドレスとサイズ)を教えてくれます。
「構造体のパディング(隙間)はどうなっているんだ?」と疑わしいとき、これを使えば一目瞭然です。
1
DCL 1 MY_REC,
2 ID CHAR(4),
2 VAL FIXED BIN(31);
/ STG(MY_REC) は、この構造体全体が何バイトかを返します /
/ 構造体のアライメントによって、思わぬサイズになっていることが分かります /
PUT SKIP LIST(‘構造体のサイズは: ‘ || STG(MY_REC) || ‘ バイトです’);
※補足:`STG`はコンパイラによって`STORAGE`関数として実装されている場合もあります。現場の環境に合わせて読み替えてくださいね。
—
実践:動的構造体を見守るデバッグ手法
現場では、このようにデバッグ用メッセージを仕込むのが定石です。
1
/ デバッグ用に、値だけでなくサイズもログに出す /
PROCEDURE OPTIONS(MAIN);
DCL MSG_BUF CHAR(50) VARYING INITIAL(‘Hello PL/I’);
/ 開発中の安全策として、メモリ情報をチェック /
PUT SKIP LIST(‘DEBUG: MSG_BUFの長さ=’ || LENGTH(MSG_BUF));
PUT SKIP LIST(‘DEBUG: MSG_BUFの占有サイズ=’ || STG(MSG_BUF));
/
もしここで予期せぬサイズになっていたら、
どこかで不正なデータ転送が行われている証拠です。
/
END;
—
まとめ:PL/Iは怖くない
いかがでしたか?
`LENGTH`で「中身の量」を測り、`STG`で「メモリの陣地」を確認する。これだけで、ブラックボックスになりがちなメインフレームのデータ処理が、ぐっと身近に感じられるはずです。
PL/Iの宣言は、一見すると呪文のように見えますが、実は非常に論理的です。メモリの構造を正しく理解し、今回紹介したツールを使いこなせれば、どんな難解なレガシーコードも必ず紐解くことができます。
皆さんのメインフレーム移行や保守作業が、少しでもスムーズに進むことを心から応援しています。また分からないことがあれば、いつでも聞きに来てくださいね。
