【入門編】ON FIXEDOVERFLOW条件の重要性 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他の言語でのご経験がある方にとって、歴史あるPL/I(ピーエルアイ)の世界は、ちょっとユニークなルールの連続に見えるかもしれませんね。

「なんだか古い言語だし、独特のお作法が多そう……」と、最初は少し身構えてしまうかもしれませんが、大丈夫です。私たちが普段書いているプログラムの本質はどの言語でも同じですし、一つひとつ紐解いていけば、怖がる必要は全くありませんよ。

今回は、PL/Iのデータ制御における非常に重要なテーマである「ON FIXEDOVERFLOW条件」について、実務の現場の匂いを感じさせつつ、優しく丁寧に解説していきますね。

—

1. 他言語出身者が驚く? PL/Iの「予約語を持たない」大らかな世界

まずは、PL/Iのちょっと変わった(そして初学者が戸惑いやすい)特徴からお話ししましょう。

JavaやCOBOLには、変数名に使えない「予約語(Keyword)」がたくさんありますよね。例えば、`IF`や`TOTAL`などをそのまま変数名にすると、コンパイルエラーになってしまいます。

ところが、PL/Iの言語仕様には、なんと「予約語が存在しない」という驚きの大らかさがあります。

1
/ こんな変数宣言も、PL/Iなら怒られません /
DCL IF FIXED(5) INIT(0);
DCL THEN FLOAT;

「えっ、じゃあコンパイラはどうやって `IF` が条件分岐なのか、変数なのかを判断しているの?」と思いますよね。
PL/Iのコンパイラは、その前後の「文脈(コンテキスト)」を読んで賢く判断しています。とはいえ、実務の現場で `IF` という名前の変数をわざわざ作る人はいませんし、そんなことをすると後からコードを読む同僚が泣いてしまいます。

ただ、この「大らかさ」の裏側で、データ型や演算に関しては非常に厳格で、時にサイレントな挙動を示す部分があります。それが今回焦点を当てる「数値の桁あふれ(オーバーフロー)」です。

—

2. FIXEDオーバーフローってなに? なぜ怖いの?

金融や流通の基幹システムを支えるメインフレームでは、金額や数量を扱うために `FIXED BINARY`(固定小数点二進数)や `FIXED DECIMAL`(ゾーン10進数・パック10進数)というデータ型を頻繁に使います。

例えば、以下のような宣言をしたとしましょう。

1
Dcl ZURAI_KINGAKU FIXED DEC(5) INIT(0); / 最大5桁(-99999 から +99999)まで入る変数 /

ここに、日々の激しい売上計算の末に、うっかり「100,000円」という6桁のデータが入ろうとしたとき、何が起きるでしょうか?

Javaであれば、ここで迷わず `ArithmeticException`(例外)などのエラーを投げてプログラムが止まってくれます。
しかし、PL/Iの世界では、デフォルトの状態だと何もエラーを出さず、左側のあふれた桁を「サイレント(無言で)切り捨てて」、何食わぬ顔で処理を続行してしまうのです。

これが、実務の現場で最も恐れられる「サイレント・バグ」の正体です。
「昨日の日次バッチ、億単位の売上がなぜか数千円になってDBに登録されている!?」なんていう大惨事が、エラーログすら残さずに起きてしまうわけですね。恐ろしいですよね。

—

3. 救世主「ON FIXEDOVERFLOW」で例外を捕まえろ!

この「知らぬ間に数字が切り捨てられる恐怖」から私たちのシステムを守ってくれるのが、PL/Iの強力な例外処理メカニズムである `ON条件(ON-unit)` です。

あらかじめプログラムの中で、「もし固定小数点の桁あふれが起きたら、こう動きなさい」と指示(トラップ)を仕掛けておくことができます。

実際のコード例を見てみましょう。

1
————————————————————–

  • FIXEDOVERFLOW条件のハンドリングサンプルプログラム

————————————————————–
TESTOVR: PROC OPTIONS(MAIN);

/ 変数の宣言:3桁(-999 から +999)まで入る変数を定義 /
DCL SHO_GOUKEI FIXED DEC(3) INIT(0);
DCL KASAN_CHI FIXED DEC(5) INIT(0);

/ ★ ここが重要:FIXEDOVERFLOW条件の監視を有効化する /
ON FIXEDOVERFLOW
BEGIN;
PUT SKIP LIST(‘【警告】数値の桁あふれ(オーバーフロー)を検知しました!’);
PUT SKIP LIST(‘処理を中断し、異常終了コードを設定します。’);
/ 必要に応じてここでログ出力や異常終了処理を行う /
SIGNAL ERROR; / 強制的にエラーシグナルを送る /
END;

/ テスト用に、あふれる数値を代入してみる /
KASAN_CHI = 12345; / 5桁のデータ /

PUT SKIP LIST(‘加算前の合計値:’, SHO_GOUKEI);

/ 3桁の変数に5桁のデータを代入(ここでオーバーフローが発生) /
SHO_GOUKEI = KASAN_CHI;

PUT SKIP LIST(‘加算後の合計値:’, SHO_GOUKEI);

PUT SKIP LIST(‘正常終了しました(※ここには到達しません)’);

END TESTOVR;

このコードでは、`ON FIXEDOVERFLOW` というブロックを宣言することで、PL/Iコンパイラに対して「桁あふれが見つかったら、黙って切り捨てずに、この中の処理を呼び出して!」と命令しています。

もしこの `ON` 宣言を書き忘れていると、コンパイルエラーにもならず、テストもすり抜けて、本番環境でしれっとデータが壊れる原因になってしまうのです。マイグレーションや新規開発の際は、この `ON` 条件の定義漏れがないかを必ずチェックするのがプロのアーキテクトの流儀です。

—

4. まとめ:レガシーの仕様を手懐けて、堅牢なシステムを作ろう

今回は、PL/Iの識別子のユニークなルールに触れつつ、数値演算における最大の罠である `FIXEDOVERFLOW` の重要性を解説しました。

  • PL/Iは予約語を持たない大らかな言語。だからこそ文脈や記述に注意が必要。
  • FIXED演算の桁あふれは、デフォルトではエラーにならず「サイレント」にデータを破損させる。
  • `ON FIXEDOVERFLOW` を明示的に記述し、例外を確実にキャッチする仕組みを必ず組み込むこと。

「レガシーシステムの仕様は怖いもの」と思われがちですが、その裏側にある理由やメカニズムさえ分かってしまえば、現代のどの言語よりも堅牢で、信頼性の高いコードを書くことができます。

一つひとつの仕様を味方につけて、自信を持ってメインフレームの荒海を乗りこなしていきましょう!
あなたのPL/Iライフが、エラーのない平穏なものになりますように。

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