#author("2019-04-24T14:38:53+09:00","default:Miyashita","Miyashita") #author("2023-01-30T13:15:47+09:00","default:Miyashita","Miyashita") *goto文の闇 [#p6352de1] go to文は極力使用を避けたいと[[基本方針>../可読性向上・誤り防止のための基本方針(fortran版)]]で書いた.詳細を以下に.~ ***goto文を使うことの欠点 [#u72b5548] #contents go to 文は極力使用を避けたいと[[基本方針>../可読性向上・誤り防止のための基本方針(fortran版)]]で書いた.詳細を以下に.~ ***goto 文を使うことの欠点 [#u72b5548] -条件分岐の整理か難しくなる~ goto(文番号)の文番号の先には,直接式が書かれているか,continue文が必要.~ 飛んだ先が遠いと,どのような条件の場合に当該処理が実行されるかorされないか,整理が大変.~ goto (文番号)の文番号の先には,直接式が書かれているか,continue 文が必要.~ 飛んだ先が遠いと,どのような条件の場合に当該処理が実行されるか or されないか,整理が大変.~ 計算フローが追いにくいと,後にインデントで見やすくしようとすることすら面倒になる.~ -不要なcontinue文を許容し,必要な部分が不明瞭になる~ continue文は参照される可能性がない場合もコンパイルが通ってしまう.例えば... -不要な continue 文を許容し,必要な部分が不明瞭になる~ continue 文は参照される可能性がない場合もコンパイルが通ってしまう.例えば... #codeprettify(lang-fortran){{ do I=1,10 ...(goto文のない記述)... 201 continue 202 continue ...(goto文のない記述)... enddo }} コンパイルオプションを付ければ警告くらいは出るかも?~ しかし,何にも使われないダミーのcontinue文は,必要だと思っていた文が実は違った,などが頻発し,デバッグに余計な時間がかかる.~ しかし,何にも使われないダミーの continue 文は,必要だと思っていた文が実は違った,などが頻発し,デバッグに余計な時間がかかる.~ -無限ループにハマる可能性がある~ (当たり前の話ではあるものの)~ 先へ進むしかないgoto文ならまだしも,戻るgoto文は条件に何らかの誤りがあった際には無限に計算が繰り返されるというリスクがある.~ 収束計算ではある程度やむを得ないかもしれない.ただし,収束計算もdo文で実行し,ある回数の間に収束しなければ脱出しエラーを返す,ということもできる.~ 先へ進むしかない goto 文ならまだしも,戻る goto 文は条件に何らかの誤りがあった際には無限に計算が繰り返されるというリスクがある.~ 収束計算ではある程度やむを得ないかもしれない.ただし,収束計算も do 文で実行し,ある回数の間に収束しなければ脱出しエラーを返す,ということもできる.~ 以上の理由より,goto文は避けたい.改善例を以下に示す.~ ***(1) if,go to~continue(ループの末尾)はcycleで代用 [#g72caa85] まず,doループの結語には,enddoとcontinueの2通りがある.~ enddoを使用した場合にも文番号があって構わないが,不要なのでここでは省略する.~ ある条件(hogeとする)を満たした場合に次のIへジャンプしたい場合は,以下の方法で可能.どちらも同じなら例2より例1の記述にしたい. 以上の理由より,goto 文は避けたい.改善例を以下に示す.~ ***(1) if, go to~continue (ループの末尾)は cycle で代用 [#g72caa85] まず,do ループの結語には,enddo と continue の2通りがある.~ enddo を使用した場合にも文番号があって構わないが,不要なのでここでは省略する.~ ある条件(hoge とする)を満たした場合に次のIへジャンプしたい場合は,以下の方法で可能.どちらも同じなら例2より例1の記述にしたい. #codeprettify(lang-fortran){{ !!例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の方が見やすいかも.しかし,continue は do 文の結語以外にも利用できるので,他と混同される可能性がある.~ ***(2)if,go to~continue(ループの末尾以外)はif(not),thenで代用 [#w582f3e0] gotoの先がdo文の終端でない場合には,if(hoge)then→endifで代用する. ***(2)if,go to~continue (ループの末尾以外)は if(not), then で代用 [#w582f3e0] goto の先が do 文の終端でない場合には,if(hoge) then → endif で代用する. #codeprettify(lang-fortran){{ !(修正前) if(hoge) goto 501 ...(処理A).. 501 continue ...(処理B)... }} #codeprettify(lang-fortran){{ !(修正後) if (not(hoge))then ...(処理A).. endif ...(処理B)... }} ***(3)文番号を使用する方が見やすい場合もあるけれども… [#qdb4e1a3] なるべくインデントで代用したい.~ 文番号はformat文で必須であり,さらにgoto文もとなると番号付けに区別をつけるのが面倒.~ ifの後にインデントをすることが見やすくするための常套手段か.~ 何重ものif文によってインデントしすぎてしまう場合は,論理構造自体を見直すか,その部分をサブルーチンにして見やすくする,といった工夫が必要になる. 文番号は format 文で必須であり,さらに goto 文もとなると番号付けに区別をつけるのが面倒.~ if の後にインデントをすることが見やすくするための常套手段か.~ 何重もの if 文によってインデントしすぎてしまう場合は,論理構造自体を見直すか,その部分をサブルーチンにして見やすくする,といった工夫が必要になる.