PL/Iの深淵:条件式評価の「短絡」が引き起こす罠と、コンパイラ最適化の現場学
メインフレームの現場で何十年と稼働し続けるPL/Iコードは、ある種のアートです。特に、現代の言語にはない「予約語を持たない」という仕様は、自由度の代償として、稀にプログラマの意図を超えた挙動をコンパイラに許してしまいます。
今日は、基幹システムの保守やマイグレーションの現場で、まさに「死神の鎌」のようにエンジニアの首を絞めることがある`IF-THEN-ELSE`の評価順序と、その最適化について、実務的な視点で深掘りしていきます。
1. 「短絡評価」の幻想とPL/Iの現実
C言語やJavaに慣れたエンジニアは、`IF (A & B)` と書けば `A` が偽なら `B` は評価されない(短絡評価)ことを前提にコードを組みます。しかし、PL/Iの世界では、この挙動はコンパイラの最適化オプションやコードの書き方に大きく依存します。
PL/Iの条件式は、基本的に「完全評価」を行うのがデフォルトの挙動です。つまり、`IF (P -> VALIDATE_FUNC() & Q)` という記述において、たとえ `P` が `NULL` であっても、`VALIDATE_FUNC()` が実行されてしまい、悲劇の「S0C4 ABEND(アドレス指定例外)」を招くケースが後を絶ちません。
実例:ポインタ参照と条件式の衝突
/ ポインタがNULLの可能性がある場合、短絡評価を期待してはいけない /
IF (PTR_PTR -> DATA_AREA.STATUS = ‘A’) & (PTR_PTR -> DATA_AREA.VALUE > 0) THEN
DO;
/ ここに来る前に、PTR_PTRがNULLだとS0C4で落ちる /
END;
これを回避するためには、論理演算に頼らず、明示的なネストが必要です。
/ 安全なコードへの書き換え:コンパイラに依存しない確実な評価 /
IF PTR_PTR ^= NULL() THEN
IF PTR_PTR -> DATA_AREA.STATUS = ‘A’ THEN
IF PTR_PTR -> DATA_AREA.VALUE > 0 THEN
DO;
/ 安全に処理を実行 /
END;
2. コンパイラ最適化と「分岐予測」の真実
IBM Enterprise PL/Iコンパイラの `OPTIMIZE(3)` を指定すると、コンパイラはコードの実行パスを徹底的に解析し、レジスタへの変数の詰め込みや、命令の並べ替えを強行します。
ここで注意すべきは、「条件分岐の予測最適化」が、副作用のある関数呼び出しを隠蔽してしまうケースです。特にDB2の埋め込みSQLを含む処理や、CICSのコモンエリアを操作する関数を条件式の中に突っ込んでいる場合、最適化によって「評価順序が入れ替わる」ことがあります。
- 推奨事項: 条件式の中には、副作用(DB更新、ポインタの移動、グローバル変数の書き換え)を持つ関数やプロシージャを絶対に記述してはいけません。
- ダンプ解析のヒント: もしABENDが発生し、CEE3DMP(ダンプリスト)を確認しても「ソース上のどの行か特定できない」場合は、コンパイラが命令を最適化して再配置した可能性を疑ってください。その際、コンパイラリストの`OBJECT LIST`を確認し、生成されたマシン命令(アセンブラコード)と照らし合わせるのが、真のアーキテクトの仕事です。
3. マイグレーションにおける「パックデシマル」の暗礁
JavaやC#への移行を検討する際、最も頭を抱えるのがPL/I特有のデータ型、特にパックデシマル(`FIXED DECIMAL`)の符号処理です。
PL/Iでは、パックデシマルの内部表現において「符号なし」で処理されるケースや、特定の演算で符号が反転する挙動が、ハードウェアレベルで最適化されています。C#の `decimal` 型やJavaの `BigDecimal` に単純置換すると、この「符号ビットの微妙な扱い」の差異で、計算結果が1円単位でズレるバグが混入します。
/ パックデシマルの符号反転の罠に注意 /
DCL PK_VAL FIXED DEC(5,0);
PK_VAL = -123;
/ メモリ上では X’123D’ のように表現される。このDを正しく扱えるか? /
移行先では、必ずバイナリレベルでの比較テスト(スナップショット・コンペア)を導入してください。移行前後のシステムから出力された物理ダンプを比較し、バイト単位で一致を確認する。これこそが、数十年動いてきた基幹システムに対する、我々アーキテクトの最低限の礼儀です。
最後に:レガシーは「悪」ではない
PL/IのコードをJava等のモダンな言語へ書き換える際、多くの人は「古いから非効率だ」と考えがちです。しかし、汎用機のコンパイラが数十年かけて磨き上げてきた最適化技術は、現代の言語の実行環境でも未だに到達できない領域があります。
`IF` 文一つとっても、そこにはハードウェアへの敬意と、限られたリソースを使い切るための知恵が詰まっています。皆さんがマイグレーションの設計を行う際、単にコードを翻訳するのではなく、その「背後にある計算の意図」を汲み取ってください。
何かトラブルがあれば、迷わずコンパイラリストを広げましょう。そこには、機械が解釈した「真実の論理」が、嘘偽りなく記されています。
