1. 導入:なぜ %LENGTH を使うべきなのか
メインフレームのPL/I開発現場において、固定長変数のサイズ定義をハードコーディングしていませんか?「DCL BUFFER CHAR(80);」のように数値を直書きすると、後から元の定義が変更された際に、関連するすべてのバッファサイズを修正し忘れるリスクがあります。%LENGTH を活用することで、定義の変更に追従する「変更に強いコード」を実現し、手動計算によるバッファオーバーフローやメモリ領域の切り詰めミスを未然に防ぐことができます。
2. 基礎知識:プリプロセッサでの解決
%LENGTH は、PL/Iのプリプロセッサ(コンパイル前のソース解析段階)で動作する組込関数です。ここでのポイントは、コンパイル後の実行時(ランタイム)に長さを評価するのではなく、コンパイル時にソースコード上の文字列長を確定させるという点です。これにより、プログラムの実行効率を落とすことなく、宣言の動的なサイズ定義を可能にします。
3. 実装と解決策
実務では、データレイアウト(構造体)の定義と、それを受け取るバッファの定義を連動させるのが最も効率的です。マスター定義(COPYメンバなど)の長さを %LENGTH で取得し、バッファ宣言に反映させます。これにより、レイアウト変更時に一箇所を直すだけで、関連する全てのバッファサイズが自動的に追従します。
4. サンプルプログラム
以下に、COPYメンバから取り込んだ定義に基づいて、バッファを自動生成する例を示します。
/ COPYメンバ等の定義を想定 /
DCL 1 TEMPLATE_REC,
2 ID CHAR(10),
2 NAME CHAR(40);
/ %LENGTHを使用してバッファサイズを動的に決定 /
/ TEMPLATE_RECの長さを取得し、そのままバッファ領域として確保する /
DCL WORK_BUF CHAR(%LENGTH(TEMPLATE_REC));
/ 以下は動作確認用のロジック /
PROCEDURE;
/ 確保された領域に値を代入 /
WORK_BUF = ‘データ転送用バッファ’;
/ 実際にはバッファ長をログ出力して確認するなどの処理を行う /
PUT SKIP LIST(‘バッファサイズは:’ || %LENGTH(TEMPLATE_REC) || ‘バイトです’);
END;
5. 応用・注意点
注意点:前述の通り、これは「コンパイル時」に解決されるものです。動的な(プログラム実行時に値が変わる)変数の長さを取得するものではありません。もし実行時の長さを取得したい場合は、STG(STORAGE)関数や別のランタイム関数を使用する必要があります。
現場のヒント:大規模システムでは、構造体をCOPYメンバで管理することが多いはずです。%LENGTH を使用することで、COPYメンバ側でフィールド長を拡張した際、再コンパイルするだけでバッファサイズが正しく引き継がれるため、保守性が飛躍的に向上します。「ハードコーディングを避ける」ことは、メインフレーム開発におけるデグレード防止の第一歩です。ぜひ、既存の宣言部を見直してみてください。

コメント