【PL/I学習|初心者向け】PL/I開発の落とし穴:SIZE条件で「データの消失」を防ぐ方法

1. 導入:なぜSIZE条件が重要なのか

メインフレームのPL/I開発において、データの代入は日常的な処理です。しかし、代入先の変数の桁数が足りない場合、PL/Iはエラーを出さずに「上位桁を切り捨てる」という挙動をすることがあります。この「黙ってデータを捨てる」という仕様は、計算ミスやデータ不整合の最大の原因です。SIZE条件を理解し適切に活用することは、バグを未然に防ぎ、堅牢なシステムを構築するために極めて重要です。

2. 基礎知識:FIXEDOVERFLOWとの違い

まず、混同しやすい「FIXEDOVERFLOW」と「SIZE」の違いを整理しましょう。
FIXEDOVERFLOWは、計算の「中間結果」が溢れたときに発生します。一方、SIZEは「計算結果を代入先の変数に格納しようとした瞬間」に、その変数の桁数(精度)を超えてしまう場合に発生します。
PL/Iでは、コンパイルオプションでNOSIZE(SIZE条件を無効化)を指定するのが一般的です。これは性能を優先するためですが、NOSIZE環境下では、溢れた上位桁は容赦なく捨てられます。これが「気付かないうちにデータが破壊される」という最悪のバグを生むのです。

3. 実装と解決策

SIZE条件を有効にするには、対象となるブロックやステートメントに条件プレフィックスを記述します。これにより、代入時に精度を超過した場合、ON SIZEブロックが実行され、エラーを検知できるようになります。古いシステムを現代の環境へ移行する際、このチェックを入れずに移行すると、隠れた桁落ちバグが表面化することがあります。

4. サンプルプログラム

以下のコードは、SIZE条件を使ってデータの溢れを検知する例です。

/ SIZE条件のテストプログラム /
TEST_SIZE: PROC OPTIONS(MAIN);

DCL VAL FIXED DEC(3,0); / 3桁まで保持可能な変数 /
DCL BIG_VAL FIXED DEC(5,0) INIT(99999);

/ SIZE条件を有効化 /
(SIZE): BEGIN;
ON SIZE BEGIN;
PUT SKIP LIST(‘警告: 代入先の桁数が不足しています!’);
END;

/ 99999を3桁の変数に入れるため、ここでSIZE条件が発生する /
VAL = BIG_VAL;

PUT SKIP LIST(‘代入後のVALの値は: ‘ || VAL);
END;

END TEST_SIZE;

5. 応用・注意点

現場での運用上の注意点をいくつか挙げます。
まず、本番環境でのパフォーマンスについてです。SIZE条件を常に有効にすると、すべての代入処理にチェックが入るため、CPU負荷が増大します。そのため、本番ではNOSIZEとするのが定石です。
次に、移行プロジェクトでの注意です。もし古いコードが「意図的に上位桁を捨てる」という仕様に依存している場合、SIZE条件を有効にするとエラーでプログラムが止まってしまいます。既存コードの挙動を調査する際は、コンパイルオプションだけでなく、ソース内の条件プレフィックスの有無も必ず確認してください。バグを見つけるための強力なツールですが、使い方を誤るとシステムを止めてしまう諸刃の剣であることを忘れないでください。

コメント

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