1. 導入
メインフレームのPL/I開発において、メモリ管理は常に頭を悩ませる課題です。特に、実行時まで要素数が確定しない「可変長配列」を扱う際、手動でサイズ変数を管理してループを制御していませんか?今回のTipsでは、BASED変数と「記述子(Descriptor)」の仕組みを理解することで、PL/Iが本来持つ強力な抽象化能力を引き出し、コードの可読性と保守性を飛躍的に向上させる手法を解説します。
2. 基礎知識
PL/IにおけるBASED変数は、特定のメモリ領域を指し示す「ポインタ」を介してアクセスする変数です。特筆すべきは、配列定義時に「()」と指定することで、コンパイル時には要素数を確定させず、実行時のALLOCATE時にそのサイズを動的に決定できる点です。
このとき、PL/Iのランタイムはメモリ上に「記述子(Descriptor)」という隠し情報を生成します。この記述子には、配列の開始アドレスだけでなく、要素数や次元情報が含まれています。そのため、プログラマは `PTR->ARRAY(I)` と記述するだけで、コンパイラが自動的に記述子を参照し、適切なオフセット計算を行ってくれるのです。
3. 実装/解決策
実装の肝は、`ALLOCATE`時にサイズを明示し、そのポインタを型定義されたBASED変数に割り当てることです。これにより、複雑なポインタ演算を意識することなく、通常の配列のように直感的なインデックスアクセスが可能になります。
4. サンプルプログラム
以下に、動的に要素数を指定して配列を確保し、アクセスする実用的なコード例を示します。
/ BASED変数の定義 /
DCL 1 DYN_STRUCT BASED(P_ARR),
2 ARR_SIZE FIXED BIN(31),
2 DATA_LIST(1:) CHAR(10); / ()で動的配列を定義 /
DCL P_ARR POINTER;
DCL I FIXED BIN(31);
DCL V_REQ_SIZE FIXED BIN(31) INIT(5); / 実行時に決まるサイズ /
/ 必要なサイズ分を確保(記述子が自動的に付与される) /
ALLOCATE DYN_STRUCT SET(P_ARR) INITIAL(V_REQ_SIZE);
/ 動的配列へのアクセス /
DO I = 1 TO V_REQ_SIZE;
/ ポインタ経由でインデックスを指定 /
P_ARR->DATA_LIST(I) = ‘DATA_’ || TRIM(CHAR(I));
END;
/ 使用後の解放 /
FREE DYN_STRUCT;
5. 応用・注意点
この手法は非常に強力ですが、現代のオブジェクト指向言語(JavaやC#など)へ移行する際には注意が必要です。他言語にはPL/Iのような「記述子」という概念がメモリレベルで自動付与されないケースが多いため、移行時には「データ本体」と「サイズ情報」をセットにしたクラス設計への変換が必須となります。
また、現場で陥りやすいバグとして、`FREE`後のポインタ(ダングリングポインタ)へのアクセスが挙げられます。`ALLOCATE`直後にポインタをセットし、`FREE`直後には必ずポインタを`NULL()`で初期化する習慣を徹底してください。この基本を守るだけで、メインフレーム特有の難解なメモリ破壊系異常終了を大幅に減らすことができます。

コメント