【PL/I学習|豆知識】メインフレーム開発の落とし穴:LIKE属性と再帰的構造の制限について

導入

メインフレームのPL/I開発において、構造体の定義に便利な「LIKE属性」を活用されている方は多いでしょう。しかし、LIKE属性にはコンパイラがメモリサイズを確定させるために守らなければならない重要なルールがあります。それは「再帰的構造の禁止」です。この制約を理解していないと、コンパイルエラーに直面するだけでなく、データ構造の設計そのものを見直す必要に迫られます。今回は、なぜこの制限があるのか、そしてリスト構造をどう扱うべきかを解説します。

基礎知識

LIKE属性は、既存の構造体の定義をコピーして新しいデータ構造を作成する機能です。一方、再帰的構造とは、自分自身の型を自分の中に含んでしまう構造のことです。
なぜこれが禁止されているかというと、メインフレームのコンパイラはコンパイル時に変数の「オフセット(メモリ上の位置)」と「占有サイズ」を完全に確定させる必要があるからです。もし自分自身を再帰的に含めてしまうと、サイズを計算しようとした瞬間に無限ループが発生してしまいます。そのため、物理的なメモリ領域の確保を伴うLIKE定義では、このような再帰が許されていないのです。

実装/解決策

再帰的なデータ(木構造やリスト構造)を実装したい場合、LIKE属性で構造体を丸ごとコピーするのではなく、POINTER属性を使用して「アドレス」を格納するように設計を変更する必要があります。物理的なデータそのものを入れ子にするのではなく、別の場所にあるデータへの「住所」を持たせることで、メモリサイズを固定的に保つことができます。

サンプルプログラム

以下に、エラーになる例と、POINTER属性を用いて解決する正しい実装例を示します。

/ 間違いの例:LIKE属性で自分自身を参照するとコンパイルエラーになる /
DCL 1 NODE_ERR,
2 DATA CHAR(10),
2 NEXT LIKE NODE_ERR; / ここで再帰が発生し、サイズが確定できないためエラー /

/ 正しい例:POINTER属性を使ってアドレスを保持する /
DCL 1 NODE_OK BASED(P_NODE),
2 DATA CHAR(10),
2 NEXT_PTR POINTER; / 構造体ではなくポインタを持つことでサイズが固定される /

/ 処理のイメージ /
DCL P_NODE POINTER;
DCL P_NEXT POINTER;

/ 実際の実装では、ALLOCATE文を使用して動的にメモリを確保する /
ALLOCATE NODE_OK;
/ 次のノードへのアドレスを格納する /
NODE_OK.NEXT_PTR = P_NEXT;

応用・注意点

現代の言語(JavaやC#など)では、オブジェクト参照が標準であるため再帰的なクラス定義が容易ですが、PL/Iなどのメインフレーム言語では、物理的なメモリ配置を意識する必要があります。
現場で古いPL/Iコードを解析する際、「なぜこの構造体はPOINTERを使っているのか?」と疑問に思うことがあるかもしれません。それは単なる癖ではなく、物理的なサイズの一意性を保証し、コンパイル時のメモリ計算を成立させるための必然的な設計なのです。LIKE属性を使う際は、そのコピー元が巨大な構造体になっていないか、また再帰的な参照を意図していないかを必ず確認するようにしてください。

コメント

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