【ネタ】FORTRANでGoToキャンペーン


これは何?

GoToキャンペーンに乗っかって(激遅)FORTRANでGoTo文を書くついでに忌まわしき要素をいくつか詰め込んでみたやつです。

誤解の無いように言っておくと、現代におけるfortranでは改善されている(はずの)内容です。

お題

AtCoderの問題から適当な奴を拝借しました。
都合上、ファイルIOなどを入れてみたりしているので少し変わっています。

要約すると、鶴亀算の問題。
鶴と亀が合わせてX匹(1≤X≤100),足の数Y本(1≤Y≤100)で、与えられたX,Yの妥当性を判断し"yes","no"を出力する。

AtCoderでは入力は標準入力で与えられますが、今回はより実際に作られたプログラムっぽくファイル引き渡しにしています。

ソースコード

何はともあれソースコードを見ていただこう。

MAIN.F
      PROGRAM MAIN
      COMMON /MYDATA/ NX,NY
      CALL READ
      NKAME = NX
      IFLAG = 1
C      WRITE(6,*) NX,NY
  10  NASHI = 2*NKAME + 4*(NX-NKAME)
      IF (NASHI.EQ.NY) IFLAG = 0    
      IF (NKAME.GT.0) THEN
      NKAME = NKAME -1
      GO TO 10
      END IF
CCCCCCC 結果出力
      IF (IFLAG.EQ.0) THEN
      WRITE(6,*) "YES"
      ELSE
      WRITE(6,*) "NO"
      END IF
      STOP
      END
READ.F
      SUBROUTINE READ
      COMMON /MYDATA/ NX,NY
      OPEN(99,FILE="INPUT.DAT",STATUS="OLD")
      READ(99,*) NX,NY
      END SUBROUTINE READ

入力ファイルはこんな感じで、適当にいじれます。

INPUT.DAT
3 8

解説

GO TO文

本題です。
FORTRANでのGoTo文はなぜか、DOループで書けるところをわざわざGoTo文+文番号でやっていることがあります。
いきなり文番号だけ出てきて後から、「あの文番号にもどれ」とか言われると認知負荷がやばいですね。(慣れると読めますが。。。)

MAIN.F
      PROGRAM MAIN
    !(略)
  10  NASHI = 2*NKAME + 4*(NX-NKAME) !ここに戻る
      !(略)
      GO TO 10 !ここから↑
      !(略)
      END

時々ループの外からGoTo文と文番号使って、ループ途中に飛び込んでくる場合があってさらに頭が混乱したりしなかったり

暗黙の型宣言

fortranは静的型付け言語ですが、暗黙の型宣言というものが存在します。
特に指定しない限り、a~h,o~z始まりの変数は実数、それ以外は整数になります。
これを利用してハンガリアン記法やオレオレルールにのっとったコードが量産されます。
(今回は本数や個数はN始まりの変数としています)

COMMON文

このCOMMON文はCOMMON /ブロック名/ 変数という形で使用します。
着目すべきはブロック名が同じであれば、同じデータ領域を指します。
COMMONを乱用すると、あらゆる変数がグローバルという素晴らしい()プログラムが完成してしまいます。

固定形式

見にくいと感じるのは私だけでしょうか。すべて大文字で書かれていると更に見にくく感じます。

パンチカードを使っていた時の名残です。以下の制限事項があります。
- 1行当たり72カラムまで
- 1~5カラムには文番号、1カラム目にCor*があればコメント行
- 6カラム目は通常は空白、文字があれば継続行として認識

簡単に改善方法

GoTo文

それぞれに合った書き方をしましょう。どうしても使うなら、エラー処理のような、ソースの上から下へ行く方向にしましょう。

暗黙の型宣言

implicit noneをつけましょう。コンパイラに怒ってもらいましょう。

COMMON文

変数のスコープに気を付けながらmoduleで置き換えましょう。グローバルである必要がないなら、なるべくスコープは小さくしましょう。

固定形式

今は自由形式を使う方がいいんじゃないかな...(古いコードのメンテナンス等は除く)

最後に

GoToキャンペーンはやめといた方がいいんじゃないかなー

一番やばいのは、これがコンパイルできてしまうコンパイラがやばい

参考

NAG Fortran入門