【PL/I学習|豆知識】PL/Iにおける「隠れた変数」の正体:記憶域クラスのDEFAULT推論を理解する

1. 導入:なぜ記憶域クラスの推論が重要なのか

メインフレームのレガシーシステムを保守・改修する際、最も頭を悩ませるのが「変数の値が予期せず消える」「逆に値が残り続けて不整合を起こす」といった挙動です。これは、PL/Iにおいて変数の記憶域クラス(STATICやAUTOMATICなど)が、明示的な宣言がない場合にコンテキスト(記述場所)によって自動的に決定されることに起因します。このルールを理解していないと、設計意図とは異なる生存期間を持つ変数が生成され、重大なバグの原因となります。本稿では、この「暗黙の推論ルール」を正しく把握し、意図的なコーディングを行うためのポイントを解説します。

2. 基礎知識:記憶域クラスの役割

記憶域クラスとは、変数がメモリ上のどこに確保され、いつまでその値が保持されるかを定義する属性です。
STATIC(静的記憶域)は、プログラムの実行開始から終了まで同じメモリ領域を占有し、値が保持され続けます。
AUTOMATIC(自動記憶域)は、プロシージャが呼び出されるたびにメモリが確保され、終了とともに解放されます。再帰呼び出しを行う場合や、メモリを節約したい場合に適しています。
PL/Iでは、これらを省略すると、その変数が「どこで宣言されたか」によって自動的に割り当てられます。

3. 実装と解決策:推論ルールを制御する

基本ルールはシンプルです。プロシージャ内部(BEGINブロック等を含む)で宣言された変数は、デフォルトで AUTOMATIC となります。一方、プロシージャの外側(PACKAGEレベルや外部モジュール)で宣言された変数は、デフォルトで STATIC となります。
このルールを逆手に取り、意図しないクラスが割り当てられるのを防ぐには、可能な限り属性を明示することが鉄則です。特に移行解析や新規開発では、全ての変数に「STATIC」または「AUTOMATIC」を明記する運用を推奨します。

4. サンプルプログラム

以下のコードは、同じ名前の変数であっても、宣言位置によって記憶域が異なる例を示しています。

TEST_PROC: PROCEDURE;
    / プロシージャ内で宣言した変数は、デフォルトでAUTOMATICとなる /
    DCL VAR_AUTO FIXED BIN(31); 
    
    / 意図を明確にするため、明示的に指定することを推奨 /
    DCL VAR_STATIC STATIC FIXED BIN(31) INIT(0);

    VAR_AUTO = VAR_AUTO + 1; / 呼び出されるたびに初期化(または不定値) /
    VAR_STATIC = VAR_STATIC + 1; / 呼び出し間で値が累積される /
END TEST_PROC;

5. 応用・注意点:現場で陥りやすい罠

現場で頻発するバグの一つに、本来「STATIC」として値を保持すべき変数を、推論ルールに甘えて「AUTOMATIC」のまま放置してしまうケースがあります。特に、初期化(INIT)を伴わないAUTOMATIC変数は、前回の呼び出し時のゴミデータが残っている可能性があり、非常に危険です。

また、既存の膨大なソースコードを扱う際は、推論結果を人間が推測するのは困難です。前述の通り、解析ツールを用いて「最終的な属性」をコメントとして付与する、あるいはコンパイラのクロスリファレンスリストを出力して、実際にどのクラスとして割り当てられたかを必ず確認する癖をつけてください。明示的であることが、最も強力なバグ回避策となります。

コメント

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