現場のPL/I職人が語る:CHARACTER型とVARYING属性の「メモリの裏側」とパフォーマンスの真実
メインフレームの現場で何十年とPL/Iコードを読み込んでいると、ふと若手エンジニアからこんな質問を受ける。「なぜ固定長(固定長CHARACTER)ばかり使うのか? VARYING属性を使ったほうがコードはすっきりするのではないか?」と。
確かに、現代のオープン系言語に慣れた感覚からすれば、可変長文字列は便利に見える。しかし、IBMメインフレームのPL/Iにおけるメモリ管理の作法を知らずにVARYINGを多用すると、バッチ処理のCPU時間を無駄に浪費し、最悪の場合は領域溢れ(Storage Overlay)の温床になる。
今回は、CHARACTER型の内部構造を紐解き、なぜ我々が「あえて」固定長を好むのか、その理由を実務的観点から解説しよう。
—
1. CHARACTER(n) vs CHARACTER(n) VARYING の内部構造
まず、メモリレイアウトを理解せねばならない。
- CHARACTER(n): 指定した長さ分だけ、連続したバイト領域が割り当てられる。これ以上でもこれ以下でもない、シンプルで潔い構造だ。
- CHARACTER(n) VARYING: これは「長さフィールド」というオマケがついている。先頭の2バイト(ハーフワード)に、現在格納されている文字数が格納され、その後に実際のデータが続く。
「たかが2バイト」と思うかもしれないが、この2バイトの管理が代入のたびに走るという事実が重要だ。固定長への代入は、単純なメモリのコピー(`MVC`や`MVCL`命令レベルの挙動)で済むが、VARYINGは「現在長の更新」という処理が必ず介在する。
2. VSAMアクセスとレコード入出力の落とし穴
特にVSAM(KSDS/ESDS)への書き出しを行う際、VARYING属性は注意が必要だ。レコードフォーマットが固定長(FB)の場合、VARYING項目をそのまま書き出すと、先頭の2バイトが文字化けのように見えるデータとして物理レコードに紛れ込む。
1
/ VSAMレコード定義の例 /
DCL 1 VSAM_REC,
2 ID CHAR(5),
2 MSG_FIX CHAR(80), / 固定長は安全だが余白は空白で埋まる /
2 MSG_VAR CHAR(80) VAR; / VARYINGは物理レイアウトを考慮しないと危険 /
/ 誤った転送例 /
/ VARYINGの長さフィールドを含めて読み書きされるとデータがずれる /
物理的に固定長として設計されたファイルフォーマットに対し、PL/I側でVARYINGを使うと、その長さフィールドがファイルの一部として書き込まれてしまう。これが原因で、後続の他言語(COBOL等)による読み込みで「IDがずれた!」というトラブルを何度も見てきた。「外部インターフェースには必ず固定長を使う」、これが現場の鉄則だ。
3. 実践:効率的な文字列操作とBUILTIN関数
VARYINGを使うなら、`SUBSTR`や`LENGTH`、`TRIM`を適切に使いこなす必要がある。以下に、可変長を扱う際の実践的なコード例を示す。
1
/ 文字列処理の標準的なパターン /
PROC OPTIONS(MAIN);
DCL INPUT_STR CHAR(100) VARYING;
DCL WORK_STR CHAR(100);
DCL L FIXED BIN(15);
/ データの代入と長さの自動管理 /
INPUT_STR = ‘IBM MAINFRAME SYSTEM ‘;
/ TRIMを使用して後続空白を除去し、VARYINGへ格納 /
INPUT_STR = TRIM(INPUT_STR);
/ 組み込み関数 LENGTH を活用する /
L = LENGTH(INPUT_STR);
IF L > 0 THEN DO;
/ 固定長領域へのコピーは明示的な制限をかけるのが安全 /
WORK_STR = SUBSTR(INPUT_STR, 1, L);
END;
/ ONユニットによるエラーハンドリングの重要性 /
ON CONVERSION BEGIN;
PUT SKIP LIST(‘データ変換エラーが発生しました’);
END;
END;
4. なぜ「予約語がない」ことが重要なのか
PL/Iの特筆すべき仕様は「予約語が存在しない」ことだ。`DCL IF = 10;` と書いても、コンパイラは文脈(Context)から `IF` が変数名であることを完璧に理解する。
これは一見自由だが、コーディング標準を設けないと悲惨なコードが生まれる。特に変数名にキーワードと同じ単語(`CHAR`, `DATE`, `TIME`など)を使うと、ソースコードを読む人間が混乱する。
現場での教訓:
「言語仕様として可能であっても、読みやすさを犠牲にするコーディングは避ける」。これが保守性を高める唯一の道だ。
最後に:スペシャリストへの道
VARYING属性は、動的に長さが変わるテキスト処理や、JSON/XMLライクな可変長データを扱う際には強力な武器になる。しかし、大規模なバッチ処理において、何百万件ものループの中でVARYINGを安易に使うことは、メモリコピーのオーバーヘッドを積み重ねることと同義だ。
メインフレームの真価は、その安定した高いスループットにある。メモリの配置を意識し、CPUが最も効率的に動けるコードを書く。その積み重ねこそが、我々PL/Iエンジニアの矜持ではないだろうか。
もし、貴方のプロジェクトで「謎のCPU高騰」が起きているなら、まず固定長と可変長の混在を見直してみることをお勧めする。現場からは以上だ。
