【Fortran学習|豆知識】計算型 GOTOの歴史と、現代における賢い書き換えテクニック

1. なぜ「計算型 GOTO」を理解する必要があるのか

数値計算の現場で古いFORTRANコードをメンテナンスしていると、突然「GOTO (10, 20, 30), I」といった不可解な構文に出会うことがあります。これが「計算型 GOTO」です。現代のプログラミングでは構造化プログラミングが基本であり、この構文は「スパゲッティコード」の元凶として忌み嫌われてきました。しかし、レガシーシステムのブラックボックスを解読し、現代的なコードへ移行(リファクタリング)するためには、この仕組みを正しく理解し、安全に排除するスキルが不可欠です。

2. 基礎知識:計算型 GOTOとは何か

計算型 GOTOは、変数 I の値に応じて、カンマ区切りで列挙されたラベル(10, 20, 30)のいずれかにジャンプする制御構文です。例えば I=1 ならラベル10へ、I=2 ならラベル20へ飛びます。
現代の SELECT CASEswitch-case 文の先祖にあたる機能ですが、最大の問題点は「どこから来たのか(フローの追跡)」が困難なことと、コンパイラがプログラムの構造を最適化しにくい点にあります。

3. 実装と解決策:現代的なコードへの置換

計算型 GOTOを排除する最も推奨される手法は、SELECT CASE 構文への置き換えです。これにより、プログラムの実行パスが可視化され、コンパイラによる最適化も効きやすくなります。

以下の手順で移行を進めます。
1. 各ラベル行の処理内容を、独立したブロックとして抽出する。
2. 整数値に応じた分岐を、可読性の高い SELECT CASE に書き換える。
3. 最後に、使用されなくなったラベル行を削除する。

4. サンプルプログラム:置換の実装例

以下に、計算型 GOTOを現代的な SELECT CASE に変換する例を示します。

! --- 修正前: 計算型 GOTO (避けるべき記述) ---
! I = 2
! GOTO (100, 200, 300), I
! 100 PRINT , "処理A"
!      GOTO 400
! 200 PRINT , "処理B"
!      GOTO 400
! 300 PRINT , "処理C"
! 400 CONTINUE

! --- 修正後: SELECT CASE による現代的な記述 ---
INTEGER :: I
I = 2

SELECT CASE (I)
    CASE (1)
        ! ラベル100相当の処理
        PRINT , "処理A"
    CASE (2)
        ! ラベル200相当の処理
        PRINT , "処理B"
    CASE (3)
        ! ラベル300相当の処理
        PRINT , "処理C"
    CASE DEFAULT
        PRINT , "範囲外の値です"
END SELECT

5. 応用・注意点:移行時の罠

現場で計算型 GOTOを書き換える際、最も注意すべきは「元のコードが意図しないジャンプを行っていないか」の確認です。
古いコードでは、ラベルの後にさらなる GOTO が隠れていたり、複数の条件が同じラベルに合流する複雑なロジックが組まれていることが多々あります。

また、I の値が範囲外(例では1〜3以外)になった際、古いコードでは「何もしない」という挙動になることがありますが、現代のコードでは CASE DEFAULT を適切に設定してエラーハンドリングを行うか、元の挙動を完全に再現させる必要があります。レガシーコードの移行は、テストコードを先に作成し、挙動が変わっていないことを確認しながら進めるのが鉄則です。

コメント

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