PL/Iの深淵へようこそ:構造体を「文字列」として扱う魔法とパディングの罠
こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLを触ってきた方にとって、PL/Iという言語は少し「職人気質で無愛想なベテラン」のように見えるかもしれません。でも安心してください。この言語は、一度ルールさえ理解してしまえば、メモリを自由自在に操れる非常に強力な相棒になります。
今日は、PL/Iでシステム開発を行う上で避けて通れない、けれど少しだけ「クセ」がある「構造体(STRUCTURE)とSTRING関数の関係」についてお話しします。
—
1. PL/Iの基本:まずは「家」を建てる(DECLARE文)
PL/Iのプログラムは、`PACKAGE`や`PROCEDURE`という単位で構成されます。まずは、データを格納する「構造体」の宣言を見てみましょう。
/i
/ 顧客データを定義する構造体 /
DCL 1 CUSTOMER_REC,
2 ID FIXED BIN(15), / 2バイトの整数 /
2 NAME CHAR(10), / 10バイトの文字 /
2 ACTIVE BIT(1); / 1ビットのフラグ /
COBOLに慣れている方にはお馴染みの階層構造ですよね。でも、ここからがPL/Iの面白いところです。PL/Iは「この構造体の中身を、一気にひとまとめのデータとして扱いたい」という時に、強力な武器を提供してくれます。それが `STRING` ビルトイン関数です。
—
2. 魔法の関数「STRING」:構造体は「一枚の布」になる
`STRING(構造体名)` と書くと、PL/Iコンパイラは構造体の個々のメンバーをバラバラの箱として見るのをやめ、「メモリ上に並んだただの巨大なビット列(または文字の並び)」として認識し始めます。
例えば、通信バッファへデータを書き出したり、バイナリファイルへ一括保存したりする際、メンバーを一つずつ指定する必要はありません。
/i
DCL BUFFER CHAR(100);
/ 構造体の中身を、そのままBUFFERにコピーする /
BUFFER = STRING(CUSTOMER_REC);
これだけで、構造体内の全データが `BUFFER` にパックされます。便利ですよね!しかし……ここで初心者が必ず一度は踏む「地雷」があります。それが「アライメント(パディング)」です。
—
3. なぜデータがズレるのか?「アライメント」の正体
コンピュータは、CPUがメモリにアクセスしやすいように、データの開始位置を「キリの良い数字」に揃えようとします。これを「アライメント」と呼びます。
例えば、`FIXED BIN(15)` の後に `CHAR` が来ると、CPUが読み取りやすいように、見えない隙間(パディング)が勝手に挿入されることがあります。
- 構造体の中: [ID(2byte)] + [パディング(?)] + [NAME(10byte)]
- STRING関数の視点: このパディングを含めた「メモリの実体」をそのまま抜き出す
もし、あなたが「この構造体をバイナリとしてファイルに落とし、別の言語(Javaなど)で読み込もう」とした場合、「あれ?データが1バイトズレている!」という現象が起きます。これがパディングの仕業です。
パディングを防ぐには?
もしパディングを排除して、純粋なデータだけを詰め込みたい場合は、宣言時に `UNALIGNED` 属性を付けてあげましょう。
/i
/ パディングを入れずに、メモリを詰め込む宣言 /
DCL 1 CUSTOMER_REC UNALIGNED,
2 ID FIXED BIN(15),
2 NAME CHAR(10),
2 ACTIVE BIT(1);
こうすることで、PL/Iは「効率よりも、宣言した通りにメモリを詰めること」を優先してくれます。外部インターフェースとやり取りする際は、この `UNALIGNED` を明示するのがプロのたしなみです。
—
4. 現場からのアドバイス:怖がらずにダンプを見る
初心者の頃は、「自分の書いた構造体が実際どんなメモリ配置になっているか」がイメージできなくて当然です。そんな時は、「DUMP」を活用しましょう。
PL/Iのデバッグ機能を使って、プログラム実行中に構造体の番地を16進数で覗いてみるのです。
/i
/ 構造体の内容をダンプ出力する(デバッグ用) /
PUT DATA(CUSTOMER_REC);
`PUT DATA` を使うと、コンパイラが現在メモリに保持している値を親切に表示してくれます。パディングが入っているかどうかは、この出力結果と、あなたが計算したバイト数を比較すれば一目瞭然です。
—
まとめ:PL/Iはあなたの意図を正確に実行する
PL/Iは、他の言語よりも「メモリの物理的な姿」に近い位置で会話できる言語です。
1. STRING関数を使えば、複雑な構造体もひとまとめに扱える。
2. アライメント(パディング)は、CPUの効率化のために勝手に入る「見えない隙間」。
3. 外部連携時は `UNALIGNED` を使って、その隙間をコントロールする。
この3つさえ押さえておけば、もう構造体で迷うことはありません。基幹システムの広大なメモリ空間を、ぜひ思い通りに操ってみてください。
何か詰まったら、いつでも戻ってきてくださいね。メインフレームの深淵は、意外と温かいですよ。それでは、良いコーディングライフを!
