導入
COBOLのプログラムで最も頻繁に使用する制御構文の一つが「PERFORM UNTIL」です。しかし、実はこの「判定のタイミング」を深く理解していないために、意図しない無限ループが発生したり、ループが1回足りなかったりするバグに遭遇した経験はありませんか?今回の豆知識では、VARYING句を用いた際の前判定(BEFORE)と後判定(AFTER)の挙動の違いを整理し、現場で確実なコードを書くための知恵を共有します。
基礎知識
PERFORM UNTILは、指定した条件が真(TRUE)になるまで処理を繰り返す構文です。ここにVARYING句を加えると、カウンタ変数の初期化、増分値の加算、そして条件判定という3つの要素が連動します。ここで重要なのが、「判定が加算の前に行われるか、後に行われるか」という点です。これを明示的に制御するのがBEFORE(前判定)とAFTER(後判定)です。
実装/解決策
基本ルールは以下の通りです。
・BEFORE(デフォルト):
初期化 → 判定 → 実行 → 加算 → 判定…
最初に判定を行うため、条件次第では「1回も実行されない」可能性があります。
・AFTER:
初期化 → 実行 → 加算 → 判定…
一度処理を実行してから判定するため、「最低1回は必ず実行される」という保証が得られます。
サンプルプログラム
以下のコードは、カウンタが3を超えるまで繰り返す例です。BEFOREとAFTERの挙動の違いを比較してみてください。
IDENTIFICATION DIVISION.
PROGRAM-ID. LOOP-TEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 I PIC 9(1).
PROCEDURE DIVISION.
DISPLAY “— BEFORE (前判定) —”
PERFORM TEST-PROC VARYING I FROM 1 BY 1 UNTIL I > 3
END-PERFORM.
DISPLAY “— AFTER (後判定) —”
PERFORM TEST-PROC VARYING I FROM 1 BY 1 AFTER UNTIL I > 3
END-PERFORM.
STOP RUN.
TEST-PROC.
DISPLAY “現在のカウンタ値: ” I.
応用・注意点
現場で最も注意すべきは、「初期値がすでに終了条件を満たしている場合」です。
例えば、データファイルから読み込んだ件数が「0」である場合、BEFOREを使用するとループの中身は一度も通りません。逆に、初期化処理として「必ず1回は処理を通したい(例えば、ヘッダーの出力など)」という場合は、AFTERを使用するか、あるいはPERFORMの前に一度処理を記述する設計にするのが安全です。
また、複雑な条件判定を繰り返す場合、判定タイミングの勘違いは「デバッグ泣かせ」のバグになります。コードの仕様書には「0件時でも処理が必要か?」を明記し、意図した判定タイミングがどちらであるかをコメントに残す習慣をつけましょう。ベテランほど、こうした基本の挙動をあえて明示的に書くものです。

コメント