【COBOL学習|実務向け】COBOL現場の鉄則:PERFORM文の「再入(再帰)」が招く致命的なバグ

導入:なぜPERFORMの再入は禁じられるのか

COBOLの現場で長年保守を行っていると、時折「プログラムが突然暴走する」「意図しない場所へ制御が飛ぶ」という不可解な障害に遭遇することがあります。その原因の多くが、構造化プログラミングにおける基本中の基本である「PERFORM文の再入」を犯していることにあります。なぜこれが厳禁なのか、そしてどう回避すべきか、ベテランの視点から解説します。

基礎知識:PERFORMの仕組みとスタック破壊

COBOLの標準的な手続き(PROCEDURE DIVISION)は、再帰呼び出しを想定して設計されていません。PERFORM文が実行される際、COBOLの実行基盤は「次にどこへ戻るべきか」を示す「戻りアドレス」を内部スタックに保存します。

もし、ある段落の中で自分自身をPERFORMすると、このスタック情報が上書きされてしまいます。結果として、プログラムは正しい帰還先を見失い、無限ループに陥るか、最悪の場合はメモリ破壊を引き起こして異常終了(ABEND)に至ります。

実装と解決策:フラグ制御による構造化

再帰的な処理を行いたい場合、PERFORMを入れ子にするのではなく、「フラグによる制御」または「PERFORM THROUGHによる範囲指定」を用いるのが定石です。特に、ループ処理が必要な場合は、PERFORM文の中にIF文を組み込み、状態遷移を管理する設計に切り替えましょう。

サンプルプログラム:安全なループ処理の実装例

以下に、再入を避けつつ、再帰的なロジックを安全に実現するパターンを示します。

IDENTIFICATION DIVISION.
PROGRAM-ID. RECURSIVE-TEST.

WORKING-STORAGE SECTION.
01 WS-COUNTER PIC 9(02) VALUE 0.
01 WS-LOOP-FLG PIC X VALUE ‘Y’.

PROCEDURE DIVISION.
MAIN-LOGIC.

  • 再入を避け、フラグ制御でループを構築する

PERFORM UNTIL WS-LOOP-FLG = ‘N’
PERFORM SUB-PROCESS
END-PERFORM.

STOP RUN.

SUB-PROCESS.

  • 自身を呼び出す代わりに、条件を満たした時のみ処理を行う

ADD 1 TO WS-COUNTER.
DISPLAY ‘現在のカウント: ‘ WS-COUNTER.

IF WS-COUNTER >= 5
MOVE ‘N’ TO WS-LOOP-FLG
END-IF.

  • ここで PERFORM SUB-PROCESS を記述してはならない

応用・注意点:現場で生き残るためのテクニック

現場で最も多いミスは、複雑な業務ロジックを組んでいる最中に、うっかりと上位段落をPERFORMしてしまうケースです。これを防ぐためのポイントを挙げます。

1. モジュール分割の徹底: 処理が複雑になり、再帰が必要だと感じたら、それは単一プログラムの限界です。素直にCALL文で外部プログラムを呼び出す設計に変更しましょう。
2. PERFORM THROUGHの危険性: 範囲指定で手続きをまとめる際、意図せず自分自身を包含しないよう注意してください。
3. コードレビューの観点: レビュー時には「この段落から呼び出されている全ての段落が、上位段落を逆参照していないか」を確認するだけで、重大な障害を未然に防ぐことができます。

COBOLは古い言語ですが、その制約は「予測可能性」を高めるための先人の知恵でもあります。基本を疎かにせず、堅牢なシステムを作り上げてください。

コメント

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