【PL/I学習|実務向け】PL/IにおけるADDR関数を用いたポインタ初期化の勘所

1. 導入

メインフレーム開発において、複雑なデータ構造(連結リストやキューなど)を扱う際、ポインタの初期値設定に頭を悩ませることはありませんか?通常、ポインタのセットは実行時に代入文で行うことが多いですが、構造の基点となるポインタなどは、宣言と同時に初期化したいケースがあります。本記事では、INITIAL属性とADDR関数を組み合わせ、効率的かつ確実にメモリアドレスをリンクさせる手法を解説します。

2. 基礎知識

PL/Iにおけるポインタとは、メモリ上の特定の番地を指し示す変数です。通常、ポインタ変数はそのままだと「NULL(何も指していない)」状態です。
ここで登場するADDR関数は、指定した変数のメモリ上の先頭アドレスを返す組み込み関数です。また、INITIAL属性は変数の宣言時に初期値を代入する属性で、これらを組み合わせることで、プログラムの実行開始時点、あるいはモジュールのロード時点で、特定の変数を指し示すポインタを自動生成できます。

3. 実装/解決策

静的リンク構造を構築する場合、対象となる変数はSTATIC属性を持つことが一般的です。STATIC属性の変数はプログラムの実行中ずっと同じメモリ領域に配置されるため、ADDR関数で取得したアドレスは有効期間中ずっと不変です。AUTOMATIC属性(自動変数)に対してこれを行う場合は、スタック領域の生成タイミングに依存するため注意が必要ですが、定型的なリンク構造の構築にはこの宣言手法が最もコードを簡潔にします。

4. サンプルプログラム

以下のコードは、データ構造の先頭を指すポインタを宣言と同時に初期化する例です。

/ サンプル:ADDR関数によるポインタの初期化 /
PROC OPTIONS(MAIN);

/ 参照先となるデータ変数を定義 /
DCL MY_DATA CHAR(10) STATIC INIT(‘ABCDEFGHIJ’);

/ MY_DATAのアドレスを保持するポインタを宣言と同時に初期化 /
DCL P_PTR POINTER STATIC INIT(ADDR(MY_DATA));

/ 動作確認用の出力 /
DCL SYSPRINT FILE PRINT;

IF P_PTR -> MY_DATA = ‘ABCDEFGHIJ’ THEN
PUT SKIP LIST(‘成功:ポインタは正しく変数を指しています’);
ELSE
PUT SKIP LIST(‘失敗:ポインタのリンクに問題があります’);

END;

5. 応用・注意点

実務でこの手法を用いる際、特に注意すべきは「コンパイル単位の依存関係」です。
ADDR関数で指定する変数が、同一のコンパイル単位内にある場合は問題ありませんが、外部のコンパイル単位(別のロードモジュールなど)にある変数を指そうとすると、コンパイルエラーやリンクエラーの原因になります。

また、「変数の属性」にも注意してください。INITIAL属性によるADDRの指定は、対象変数が静的に配置されていることを前提としています。もし対象変数がAUTOMATIC属性の場合、コンパイル時にアドレスが確定できず、予期せぬ動作を招く可能性があります。複雑な構造体ポインタの初期化を行う際は、対象変数が必ずSTATIC属性であることを確認し、必要に応じて構造体全体の定義をINCLUDEメンバーとして共通化する運用を推奨します。

コメント

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