goto文の闇

go to文は極力使用を避けたいと基本方針で書いた.詳細を以下に.

goto文を使うことの欠点

  • 条件分岐の整理か難しくなる
    goto(文番号)の文番号の先には,直接式が書かれているか,continue文が必要.
    飛んだ先が遠いと,どのような条件の場合に当該処理が実行されるかorされないか,整理が大変.
    計算フローが追いにくいと,後にインデントで見やすくしようとすることすら面倒になる.
  • 不要なcontinue文を許容し,必要な部分が不明瞭になる
    continue文は参照される可能性がない場合もコンパイルが通ってしまう.例えば...
        do I=1,10
         ...(goto文のない記述)...
    201 continue
    202 continue
         ...(goto文のない記述)...
        enddo
    コンパイルオプションを付ければ警告くらいは出るかも?
    しかし,何にも使われないダミーのcontinue文は,必要だと思っていた文が実は違った,などが頻発し,デバッグに余計な時間がかかる.
  • 無限ループにハマる可能性がある
    (当たり前の話ではあるものの)
    先へ進むしかないgoto文ならまだしも,戻るgoto文は条件に何らかの誤りがあった際には無限に計算が繰り返されるというリスクがある.
    収束計算ではある程度やむを得ないかもしれない.ただし,収束計算もdo文で実行し,ある回数の間に収束しなければ脱出しエラーを返す,ということもできる.

以上の理由より,goto文は避けたい.改善例を以下に示す.

(1) if,go to~continue(ループの末尾)はcycleで代用

まず,doループの結語には,enddoとcontinueの2通りがある.
enddoを使用した場合にも文番号があって構わないが,不要なのでここでは省略する.
ある条件(hogeとする)を満たした場合に次のIへジャンプしたい場合は,以下の方法で可能.どちらも同じなら例2より例1の記述にしたい.

!!例1
    do I=IS,IE
     ...(何か)....
     if(hoge) cycle
     ....
    enddo
!!例2
    do 501 I=IS,IE
     ...(何か)....
     if(hoge) goto 501
     ....
501 continue

人によっては,例2の方が見やすいかも.しかし,continueはdo文の結語以外にも利用できるので,他と混同される可能性がある.

(2)if,go to~continue(ループの末尾以外)はif(not),thenで代用

gotoの先がdo文の終端でない場合には,if(hoge)then→endifで代用する.

!(修正前)
     if(hoge) goto 501
       ...(処理A)..
501  continue
     ...(処理B)...
!(修正後)
     if (not(hoge))then
       ...(処理A)..
     endif
     ...(処理B)...

(3)文番号を使用する方が見やすい場合もあるけれども…

なるべくインデントで代用したい.
文番号はformat文で必須であり,さらにgoto文もとなると番号付けに区別をつけるのが面倒.
ifの後にインデントをすることが見やすくするための常套手段か.
何重ものif文によってインデントしすぎてしまう場合は,論理構造自体を見直すか,その部分をサブルーチンにして見やすくする,といった工夫が必要になる.


Front page   Edit Diff Attach Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2016-12-06 (Tue) 10:00:18 (1174d)