【入門編】CHARACTER(n)とCHARACTER(n) VARYINGのメモリ構造 – PL/Iの基本構文とデータ制御実践ガイド

PL/Iの「文字列」の深淵:固定長と可変長のメモリレイアウトを紐解く

皆さん、こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLを触ってきた方にとって、PL/Iという言語は少し古風で、時に「クセが強い」と感じられるかもしれません。特に、メモリを直接扱うような感覚に近いこの言語では、データ宣言一つでプログラムの挙動やパフォーマンスが劇的に変わります。

今回は、PL/Iで最も頻繁に登場する「CHARACTER型」の内部構造について、じっくりお話ししていきましょう。

CHARACTER(n):質実剛健な「固定長」の世界

まずは `CHARACTER(n)` です。これはCOBOLの `PIC X(n)` とほぼ同じと考えて差し支えありません。

/i
DCL NAME CHAR(10); / 10バイト固定の領域を確保 /

この宣言をすると、メインフレームのメモリ上には正確に10バイトの連続した領域が確保されます。もしここに「IBM」という3文字を入れると、残りの7バイトには自動的にスペースが詰められます。

  • メリット: メモリレイアウトが完全固定なので、オフセット計算が非常に速い。
  • 注意点: 常に指定した長さ(n)分を消費するため、無駄に大きな値を宣言するとメモリを圧迫します。

CHARACTER(n) VARYING:実は「おまけ」が付いている

次に、少しトリッキーな `VARYING` 属性です。これは、その名の通り「長さが変わる」文字列です。

/i
DCL DISP_NAME CHAR(10) VARYING; / 最大10バイトだが、中身は可変 /

ここで重要なのは、「メモリ上には10バイト+αの領域が確保されている」という事実です。
実は、PL/Iの `VARYING` 文字列のメモリ先頭には、「現在の文字列長」を表す2バイトのバイナリ値(ハーフワード)が隠されているのです。

メモリレイアウトのイメージ

| 先頭2バイト(長さ情報) | 文字列データ本体 |
| :— | :— |
| `00 03` | `I B M` (残りは無視される) |

この仕組みがあるおかげで、`VARYING` 型は文字列の終わりを探すためのスキャン(NULL文字を探すような処理)が不要になり、非常に高速に長さを判定できます。

転送時の「落とし穴」に注意!

ここからが現場の知恵袋です。固定長と可変長を代入する際、初心者が陥りやすい罠があります。

1. 固定長 → 可変長への代入

`DCL F_STR CHAR(5) INIT(‘ABC’);`
`DCL V_STR CHAR(10) VARYING;`
`V_STR = F_STR;`

この場合、`F_STR` は右側にスペースが含まれているため、`V_STR` に代入するとスペースを含めた長さ(この場合は5)がセットされます。「ABC」だけを入れたつもりでも、後ろにスペースが付いてくるので注意してください。

2. 可変長 → 固定長への代入

`V_STR` に入っているのが「ABC」だけなら、`F_STR` に代入した瞬間に残りの2バイトはスペースでパディングされます。これは非常に安全な挙動ですが、データの比較時には「スペースあり・なし」の不一致に悩まされることがよくあります。

実務で役立つコード例

現場のバッチプログラムで、文字列を扱う際の推奨パターンを載せておきますね。

/i
TEST_PROC: PROCEDURE OPTIONS(MAIN);

/ 固定長は、桁数が決まっているコード類や固定レコードに使用 /
DCL EMP_ID CHAR(5) INIT(‘A001’);

/ 可変長は、メッセージや動的に生成される文字列に使用 /
DCL MSG_TEXT CHAR(50) VARYING;

/ 可変長への代入例 /
MSG_TEXT = ‘エラーが発生しました’;

/

  • ヒント:TRIM関数を組み合わせることで、
  • 固定長から転送する際の不要なスペースを除去できます。

/
MSG_TEXT = TRIM(EMP_ID);

PUT SKIP LIST(‘長さは:’ || LENGTH(MSG_TEXT));
PUT SKIP LIST(‘内容は:’ || MSG_TEXT);

END TEST_PROC;

最後に:怖がる必要はありません

「メモリの先頭に長さ情報がくっついている」と聞くと、難しそうに感じるかもしれません。しかし、PL/Iのコンパイラは優秀です。あなたが `VARYING` と宣言さえすれば、その後の長さ管理はコンパイラが裏側で完璧に処理してくれます。

皆さんが意識すべきなのは、「固定長は箱のサイズが決まっているから安心だが、スペースの扱いに注意が必要。可変長はスマートだが、メモリの先頭に長さ用の領域が隠れている」というイメージだけです。

もしバッチのマイグレーションでデータの不一致が起きたら、まずはこの「文字列の長さ」と「スペースのパディング」を疑ってみてください。それだけで、トラブル解決の速度が段違いに上がりますよ!

これからも、一緒にメインフレームの深淵を楽しく探検していきましょう。また次回お会いしましょう!

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