1. 導入:なぜスキャナの制御が必要なのか
メインフレーム開発、特にPL/I環境において、プリプロセッサによるソースコードの置換は強力な武器です。しかし、同じ名称の識別子が「ある場所では定数として置換してほしいが、別の場所では通常の変数名として扱いたい」というケースに直面することがあります。このような「コンテキスト依存の振る舞い」を制御するために用意されているのが %ACTIVATE と %DEACTIVATE です。この機能を正しく理解することは、複雑なソース解析や、レガシーコードの保守における予期せぬ置換バグを防ぐために不可欠です。
2. 基礎知識:スキャナとプリプロセッサ
PL/Iのコンパイルプロセスにおいて、プリプロセッサはソースコードを「スキャン(走査)」します。プリプロセッサ変数が有効(ACTIVE)な状態である場合、スキャナはその文字列を見つけるたびに、定義された値へ置き換えます。しかし、すべてをグローバルに有効化してしまうと、誤ってプログラム内の変数名まで置換してしまうリスクがあります。%ACTIVATE は「特定範囲のみ置換を許可」し、%DEACTIVATE は「その置換を停止」させるスイッチとして機能します。
3. 実装と解決策
実務上では、共通定義ファイル(Includeファイル)で定義されたマクロ定数を、必要なアルゴリズムの実行直前でのみ有効化し、処理が終われば即座に無効化するという「囲い込み」の手法をとります。これにより、意図しない場所での誤置換(副作用)を完全に排除できます。
4. サンプルプログラム
以下のコードは、特定の計算ロジック区間のみ定数置換を有効にする例です。
/ マクロ定数の定義 /
%DCL TAX_RATE CHAR;
%TAX_RATE = ‘0.10’;
/ 通常の処理区間:ここではTAX_RATEは置換されない /
DCL TAX_RATE FIXED DEC(5,2);
TAX_RATE = 0.05;
/ 特定の計算ロジックのみ置換を有効化 /
%ACTIVATE TAX_RATE;
/ ここでは TAX_RATE は 0.10 に置換される /
CALC_RESULT = BASE_PRICE TAX_RATE;
%DEACTIVATE TAX_RATE;
/ 再び通常の変数として扱う /
TAX_RATE = 0.08;
5. 応用・注意点:現場での運用とデバッグ
現場で最も陥りやすいバグは、%DEACTIVATEの記述漏れです。特に条件分岐(IF文やDOループ)の中で %ACTIVATE を使用する場合、論理パスによっては DEACTIVATE が実行されないまま後続処理に影響を及ぼすことがあります。
また、移行解析時には「この変数はマクロ定数なのか、それともプログラム内の変数なのか」を識別するために、プリプロセッサの制御フローを追跡する必要があります。複雑なコードでは、あえて %ACTIVATE を使わず、定数名をユニークにする(例:K_TAX_RATE のようにプレフィックスを付ける)という設計方針をとるチームも多いです。デバッグ時には、プリプロセッサの出力結果(SYSUT3等に出力される展開後ソース)を必ず確認し、意図通りに置換が制御されているかを検証してください。

コメント