「IF」が変数名になる言語?PL/Iの予約語なき設計思想と、その深淵なる罠
メインフレームの現場で何十年と生き抜いてきた諸君らなら、一度は目にしたことがあるはずだ。`IF` や `THEN`、あるいは `DECLARE` すらも、文脈次第で変数名として許容してしまうPL/Iの「寛容すぎる」言語仕様。
モダンな言語、例えばJavaやC#の設計に慣れ親しんだエンジニアが初めてPL/Iのソースコードを見たとき、しばしば戦慄を覚えるのがこの「予約語が存在しない」という仕様だ。しかし、この設計思想は決して怠慢から生まれたものではない。IBMが1960年代に目指した、「科学技術計算も事務処理も、あらゆる領域を一本の言語で統合する」という壮大な野望の帰結である。
今回は、このPL/I特有の設計思想が、現代のマイグレーションや保守の現場でどのような「牙」を剥くのか、その内側を紐解いていこう。
「文脈依存」という諸刃の剣
PL/Iのコンパイラは、コードを解析する際、単純なキーワード照合ではなく、その位置と構文的な役割から「これは識別子か、キーワードか」を動的に判断する。
1
/ 恐ろしいことに、これは文法的に正しい /
DCL IF FIXED BIN(31); / 変数名 IF を宣言 /
IF = 10; / 代入 /
IF IF = 10 THEN; / 最初のIFは予約語、二番目は変数名 /
この仕様の何が危険か。それは、メンテナンス時にうっかり予約語を変数名として使ってしまった際、コンパイラがエラーを吐かずに「意図しない挙動」を生成する可能性だ。特に、`REORDER` オプションを付けたコンパイル時、最適化ロジックが変数とキーワードの境界を曖昧に解釈し、期待したメモリ配置と異なるコードを吐き出すケースがある。
ポインタ操作とアベンドの深淵
基幹システム、特にCICS環境下での動的メモリ操作において、PL/Iのポインタ(`POINTER`)は最強の武器だが、同時にアベンド(ABEND)の最大の温床でもある。
1
DCL P PTR;
DCL TGT_AREA CHAR(100) BASED(P);
/ 動的確保時のポインタ設定 /
ALLOCATE TGT_AREA;
/ ここでポインタをずらすと、即座に S0C4 アベンドが待っている /
P = P + 4;
TGT_AREA = ‘DATA’; / オフセットがずれた状態で書き込み、致命的なメモリ破壊へ /
ここで重要な知見を共有しよう。ダンプ解析を行う際、`S0C4`(保護違反)が発生したら、まずレジスタの状態を確認し、ベースポインタが指し示す先がデータセットの境界を超えていないかを疑うべきだ。マイグレーションにおいて最も手間取るのは、この「ポインタ演算による物理的なメモリ位置への依存」を、Javaの安全なオブジェクト参照へどう変換するかという点にある。
パックデシマルと「内部符号」の落とし穴
金融系システムで頻出するパックデシマル(`PIC S9(n) COMP-3`)。この内部形式において、最下位ニブルが符号(`C`=正, `D`=負)を保持することは周知の事実だが、移行先でこの符号ビットを正しく変換できず、バグを生むケースが後を絶たない。
1
/ 意図せぬ符号反転を防ぐためのチェックルーチン例 /
DCL WORK_VAL PIC S9(7)V99 COMP-3;
IF WORK_VAL < 0 THEN DO; / 負数の場合の特殊処理:ダンプに出すと符号がDで表示される / / 移行先システムでのビット演算時には注意が必要 / END; 特に、COBOLからPL/Iへ移行する際、あるいはPL/IからJavaへ移行する際、この「符号ビットの解釈」をライブラリ任せにすると、特定の計算結果で1円のズレが生じる。これはアーキテクトとして絶対に許容してはならない「極限の信頼性」の欠如だ。
アーキテクトへの提言:移行を成功させるために
レガシー移行のプロジェクトにおいて、PL/Iのソースコードを単なる文字列変換で片付けようとするのは自殺行為である。
1. コンパイラオプションの精査: `OPTIMIZE(2)` や `REORDER` が指定されている場合、現在のコードが「コンパイラに最適化されること」を前提に書かれている可能性が高い。このロジックを読み解くのが先決だ。
2. 埋め込みSQL(DB2)のエッジケース: SQLCODEのチェック後にPL/I側で変数に値をセットする際、型変換(`FIXED BIN` から `FLOAT` への暗黙変換など)が走っていないか確認せよ。暗黙の型変換は、PL/Iの「文脈依存」という仕様と相まって、デバッグ困難な丸め誤差を引き起こす。
3. 静的解析の徹底: 識別子の命名規則が曖昧なPL/Iコードに対し、あえて現代的なネーミングルールを強制するリファクタリングを移行前に行うべきだ。
PL/Iは、その自由度ゆえに「書き手を選ぶ」言語である。しかし、この言語が持つ「極限までマシンに近いメモリ制御」と「ビジネスロジックを記述する柔軟性」を理解すれば、どんなモダンなフレームワークよりも堅牢なアーキテクチャを構築できるはずだ。
諸君らの移行プロジェクトが、単なる「置き換え」ではなく、次世代を見据えた「進化」になることを期待している。不明な点があれば、いつでもこのメインフレームの深淵へ問いかけてほしい。
