迷宮の鍵を握る「ポインタ」の正体:PL/Iアドレッシングの深淵を覗く
皆さん、こんにちは。メインフレームの世界へようこそ。
普段、JavaやCOBOLという「高層ビル」で仕事をしていると、PL/Iという言語はどこか古びた地下室のように感じられるかもしれません。確かに、PL/Iは1960年代生まれのベテランですが、その設計思想の柔軟さは、現代の言語にも引けを取りません。
今日は、そんなPL/Iの中でも、特に「ポインタ(POINTER)」という、少しだけとっつきにくい、しかし最強の武器について紐解いていきましょう。
—
1. ポインタって、結局何者なの?
Javaで言えば「参照(Reference)」、C言語で言えば「アドレスを指す変数」。PL/Iのポインタもまさにそれです。
メモリ上のどこにデータがあるかを指し示す「住所」を保持する変数ですね。
ただ、メインフレームの歴史は長く、「31ビット・アドレッシング」という過去の遺産と、「64ビット・アドレッシング」という現代の広い宇宙が共存しています。この2つの世界で、ポインタの「中身」がどうなっているのか、イメージしてみましょう。
31ビットと64ビットの違い
かつてメインフレームは24ビット(16MB)の壁と戦っていました。その後、31ビット(2GB)へ拡張され、現在は64ビット(理論上は無限に近い)の世界にあります。
- 31ビット・ポインタ: 4バイトの領域に、データへの住所を詰め込みます。
- 64ビット・ポインタ: 8バイトの領域を使います。
ここで注意が必要なのは、「古いプログラム(31ビット)と新しいプログラム(64ビット)が混在する環境では、ポインタの形が異なる」ということです。これが、レガシー移行の現場でよく起こる「アドレス例外(ABEND 0C4など)」の主犯格なのです。
—
2. PL/Iのポインタをコードで見てみる
PL/Iのポインタ宣言は、COBOLの`USAGE IS POINTER`よりもずっと直感的です。
実際に、動的メモリ確保(ALLOCATE)を行う例を見てみましょう。
/i
/ プログラムの基本骨格:PACKAGEはモジュールの単位です /
DEMO_POINTER: PACKAGE;
/ メイン処理のエントリポイント /
PROCESS_MAIN: PROCEDURE OPTIONS(MAIN);
/ 1. ポインタ変数の宣言:これ自体は「住所」しか持っていません /
DCL MY_PTR POINTER;
/ 2. データ構造(基底)の定義: BASED属性がポイントです /
DCL MY_DATA CHAR(10) BASED(MY_PTR);
/ 3. メモリの確保:ここで初めてMY_PTRに住所が入ります /
ALLOCATE MY_DATA;
/ 4. 値の代入:ポインタを経由してデータを操作 /
MY_DATA = ‘HELLO PL/I’;
/ 5. 確認:メモリの内容を表示 /
PUT SKIP LIST(‘確保したデータは:’ || MY_DATA);
/ 6. 後始末:忘れずに解放しましょう /
FREE MY_DATA;
END PROCESS_MAIN;
END DEMO_POINTER;
なぜ「BASED」を使うのか?
PL/Iの面白いところは、データそのもの(MY_DATA)に、「どこにあるか(MY_PTR)」という属性を後付けできる点です。
これは、COBOLのように固定的なデータレイアウトではなく、実行時に「このメモリ領域を、この構造体として扱う」という動的な制御が非常に得意であることを意味しています。
—
3. セグメント間参照の「落とし穴」
メインフレームのシステム開発で最も恐ろしいのは、「異なるアドレス空間(セグメント)を跨ぐとき」です。
例えば、あるバッチ処理が31ビットで動いていて、呼び出し先のサブモジュールが64ビットでコンパイルされていた場合、ポインタを渡した瞬間に「住所」の長さが合わず、システムは混乱します。
- 制限事項のイメージ:
31ビットの世界の人に「100番地の住所」を渡しても、64ビットの世界の人には「その100番地は、広大な64ビット空間のほんの入り口なのか、あるいは全く別の場所なのか」が判別できないことがあります。
- 解決のヒント:
移行時には、コンパイルオプション(`ADDR(31)`か`ADDR(64)`か)を厳密に合わせる必要があります。もし混在させる必要があるなら、IBMが提供する「ポインタ変換ユーティリティ」を使用して、慎重に橋渡しを行わなければなりません。
—
最後に:怖がる必要はありません
「ポインタなんて触りたくない」と思うかもしれません。でも、ポインタを理解するということは、「コンピュータがメモリをどう管理しているか」を直接手懐けるということです。
PL/Iは、その名の通り「Programming Language One(第一の言語)」として、非常にパワフルで論理的な構造を持っています。一度この「住所」の考え方に慣れてしまえば、他の言語でのメモリ管理も格段に理解しやすくなるはずです。
もし、実務で「0C4」エラーに悩まされたら、まずは「そのポインタが指している住所は、今どっちの世界(31bit/64bit)のルールで見ているのか?」を疑ってみてください。
皆さんのメインフレーム・ライフが、少しでも快適なものになりますように。また次回、さらなる深淵でお会いしましょう!
