FORTRAN 77の言語仕様

FORTRAN 77の言語仕様は、FORTRAN 66とFORTRAN 77の言語仕様と、言語仕様にまつわるエピソードについて解説している。なお、Fortran 90以降の言語仕様については、Fortranの言語仕様を参照のこと。

1. 言語仕様
-------

Fortranの言語仕様は、年代によってかなり変化して来ている。他のプログラミング言語で実装された構造化プログラミングの機能などがどんどん取り入れられて来ているからである。

1.1. FORTRAN 66
---------------

FORTRAN 66の言語仕様はおおよそ下記のとおり。

1.1.1. 利用できる文字
--------------

英数字
特殊文字

1.1.2. プログラムの書式
---------------

プログラムは以下の形式で記述する。もともとパンチカードに書くことを前提としていたので、1行は80文字で構成されていた。行の左端からの文字位置を桁またはカラムと呼んだ。

もともとのFORTRANは、字句解析の仕組みがCやJavaと大きく異なり、桁位置に依存していた。これを//固定プログラム形式//という。これは、当時、データの入力にパンチカードを 使用していたためである。1桁目から5桁目が文番号で、6桁目が継続行の指定、7桁目から72桁目に文の本体を記述する。73桁目から80桁目は任意に指定可能な、行を識別するための文字列を記述する領域である。また、文字列定数中以外の空白文字は一切無視されていた。二つ以上の字句を空白無しで続けて書 いたり、逆に一つの字句の途中に空白文字を入れても構わない。

1～5桁目 文番号を書く。1カラム目にCを書くとその行はコメント行になる。 6桁目 継続行であるときはここに任意の文字を書く 7～72桁目 本文を書く 73～80桁目 シーケンシャル番号を書く物理的に穴を開けるパンチカードのほかに、鉛筆で塗りつぶすマークシート方式も存在した。消しゴムで消せば楽に修正できるわけである。いずれも、カード1枚がプログラム1行に相当する。これらは「FORTRANカード」と呼ばれた。

1.1.3. 数など
----------

以下の数を扱える。

整数
単精度実数
倍精度実数
複素数
論理型
文字型

1.1.4. 変数など
-----------

以下の変数宣言を扱える。

暗黙の型宣言
整数型
実数型
明示的な型宣言
INTEGER宣言文
REAL宣言文
DOUBLE宣言文
COMPLEX宣言文
LOGICAL宣言文
配列

1.1.5. 式
--------

算術式
比較
論理演算

1.1.6. 文
--------

実行文 代入文 ASSIGN文:ASSIGN文で変数に割り当て、次の割当て型GO TO文で割り当てられた文番号にジャンプする。 制御文 単純GO TO文 計算型GO TO文:飛び先がリストされていて、その後にある変数の内容を評価し、その値によって飛び先にジャンプする。 割当て型GO TO文:ASSIGN文で割り当てられた飛び先にジャンプする。 算術IF文:値を評価し、その値がマイナス、0、プラスによって3方向にジャンプする。 論理IF文:現在主流のプログラミング言語では、ごく一般的なif文。値の真偽値に基づき、真なら命令文を実行する。 CALL文:サブルーチン副プログラムを呼び出す。 RETURN文:サブルーチン副プログラムで、呼出し元に戻る。 DO文:繰り返しを構成する。制御変数は整数型のみ。 CONTINUE文:それ自身では何もしない。通常、DO文の終端を示すのに使われる。 STOP文:プログラムの実行を終了する。 PAUSE文:プログラムを一旦中止し、コンソール上にメッセージを出す。記述できるメッセージは数字のみ 入出力文 READ文:デバイスと書式を指定し、リストされた変数に値を入力する。デバイスは数字。5がカードリーダ入力、6がラインプリンタにあらかじめ指定されていることが多い。書式無しのREAD文もある WRITE文:READ文の逆で、リストされた変数の内容を書式に従って出力する。 補助入出力文:磁気テープ装置の入出力を行いやすくするために使われるのが基本。 REWIND文:読み出し又は書き込み位置を装置の先頭に位置づける。 BACKSPACE文:一つ前の記録位置に位置づける。 END FILE文:ファイルエンドマークを記録する。 宣言文 DIMENSION文:配列を定義する。 COMMON文:プログラム間での共通領域を定義する。 EQUIVALENCE文:ある変数と別の変数を同じ物とみなす。 EXTERNAL文:外部手続きであることを宣言する。 型宣言文:型宣言文は配列定義も兼ねられる。 INTEGER文 REAL文 DOUBLE PRECISION文 COMPLEX文 LOGICAL文 DATA文:初期データを定義する場合に利用する。 FORMAT文:各種の書式を定義する。 型変換 I変換:整数の変換 F変換:小数点付きの実数の変換 E変換:指数
表示の実数の変換 D変換:指数表示の倍精度実数の変換 G変換:桁数に応じて、EまたはF変換 L変換:論理型の変換 H変換:桁数指定の文字列の変換。プリンタに出力する場合、行の最初の桁が改行指示となる。 +:行送りなし 空白:1行送り 0:2行送り 1:改ページ A変換:文字列の変換 副プログラム関連 FUNCTION文 SUBROUTINE文 BLOCK DATA文

1.1.7. 関数
---------

以下の関数を扱える。

文関数 そのプログラム内で有効な関数定義を1行で記述する。 組込み関数 組込み関数は、同じ機能でも引数の型と関数の型によって名前が異なる。関数名の先頭がI～Nのものが整数型、Dが倍精度実数型、Cが複素数型、それ以外が実数型である。 絶対値 切捨て 剰余 最大値 最小値 実数化 整数化 符号の付け替え 超過分 単精度実数化 倍精度実数化 複素数の実数部 複素数の虚数部 複素数化 共役複素数 外部関数 あらかじめライブラリとして提供されている関数 関数副プログラム 関数副プログラムは、FUNCTION文で始まるサブルーチンである。 平方根 指数 自然対数 常用対数 正弦 余弦 逆正接 剰余 絶対値

1.2. FORTRAN 77
---------------

FORTRAN 77は、FORTRAN 66に、よりプログラムを書きやすくするための文や、動作の明確化をはかっている。FORTRAN 66でのプログラムはほぼそのまま動くようになっている。以下はFORTRAN 77で追加/変更になった点の概要である。

1.2.1. 数など
----------

文字列を指定するのに、アポストロフィが使えるようになった。例えば。

1.2.2. 変数など
-----------

変数などについて以下の変更が加えられた。

IMPLICIT文で、暗黙の型宣言の範囲を変更できるようになった。一部のコンパイラではすでに実装されていたものを仕様化したものである。整数、実数だけではなく、文字型なども指定できる。
PARAMETER文で、定数に名前を与えられるようになった。FORTRAN 66では、定数は、直接式に書くか、変数を定数代わりに使う方法しかなかった。前者は定数の変更に手間がかかり、後者は定数を変更されてしまう危険性があった。
配列の宣言に寸法宣言子を指定できるようになった。FORTRAN 66では配列は1から始まるだけだったが、FORTRAN 77ではマイナスの領域も定義できるようになった。たとえば以下のように定義できる。 DIMENSION ARRAY 
部分文字列が利用できるようになった。配列と同じような形で指定できる。 CHARACTER*4 CHR CHR = "2B"
配列の初期化にDO形並びが利用できるようになった

1.2.3. 式
--------

型の異なる変数/定数間での型の変換方法が定義された
文字の連結演算子が定義された
論理演算子に、等しければ真となる.EQV.と、異なれば真となる.NEQV.が定義された

1.2.4. 文
--------

宣言文
IMPLICIT文が追加された
副プログラムで、そのプログラム内で定義した変数を、そのプログラム内から抜け出たときも値が不定にならないように、保存するSAVE文が追加された。
主プログラム名を指定するPROGRAM文が追加された。
実行文
IF構造として、IF THEN～ と IF THEN～ELSE～END が利用できるようになった。
入出力文
入出力文の書式が大幅に強化された。以下のパラメータが利用できるようになった。これらを使うことで、入出力操作の柔軟性が向上した。
UNIT=
FMT=
ERR=
END=
IOSTAT=
REC=
補助入出力文に以下の文が追加された
OPEN文
CLOSE文
INQUIRE文

1.2.5. 関数
---------

以下の関数が追加された。

文字長
部分列の位置
正接
逆正接
逆余弦
逆正接
双曲線正弦
双曲線余弦
双曲線正接
文字列の大小比較

2. FORTRANの言語仕様にまつわるエピソード
-------------------------

2.1. 「暗黙の型宣言」による伝統的・慣習上の変数命名規則
------------------------------

FORTRANのプログラムにおいては、とくに型宣言をしない場合、アルファベットI,J,K,L,M,Nのいずれかで始まる変数名で表される変数は整数型になり、その他のアルファベットで始まるものは実数型になる。これが「暗黙の型宣言」といわれるFORTRANの文法上の規則である。なお、この命名規則についてBakusは『Iから始まる6文字に決まったのは、みんな添え字にI、J、Kをつかっていたので、気前よく増やした。』と言っている。

FORTRANのプログラムでは、特にループ構造を表すDO構文におけるカウンター変数としてアルファベットI～Nの1文字の変数名が伝統的によく使用されており、プログラミングにおける慣習上の変数命名規則の一つとなっている。i, j,...の1文字変数をインデックス参照などに使われるループカウンタに使うことは、他の多くのプログラミング言語に伝搬したが、プログラミング言語における慣習としてはFORTRANに由来する。

いくつかの観点から、変数には明示的な宣言が必要とされることもある。Fortran 90以降ではIMPLICIT NONE文により暗黙の型宣言を無効にできるようになった。コンパイラのエラーメッセージや警告により暗黙の型宣言に起因するバグの発見が容易になるので積極的に用いるべきである。

2.2. 言語仕様と宇宙開発にまつわるエピソード
------------------------

FORTRANの「空白は無視する」という言語仕様が招く、コンマとピリオドの打ち間違いがコンパイルエラーにならず、間違ったプログラムになる、という例を説明する。

Cで、次のように書くプログラムの一部があったとする。

int i;  for { 何らかの処理; }

これをFORTRAN66で書くと次のように書ける。

DO 10 I=1,5 何らかの処理 10 CONTINUE

最初の行は、整数型変数Iを1から5まで1ずつ増加させつつ、行ラベル10の行までを繰り返し実行することを表す。行ラベル10のCONTINUE文はループ制御の//端末文ではなく//、どこにでも置ける「何もしない」機能の文である。

この、DO文のコンマをピリオドに打ち間違えたとする。すると、空白を無視するFORTRAN66では、この行は、 DO10I=1.5 という、「DO10Iという実数型変数に1.5という実数を代入する代入文」と解釈される。FORTRANでは変数宣言が無い場合、DO10Iは実数型変数を暗黙に示すからである。 この結果、このプログラムは変数DO10Iへの代入とただ1回の「何らかの処理」が実行されるだけとなり、意図した繰り返し処理は起こらない。

C言語などでは、空白文字は字句要素の切れ目として解釈されるため、DO と 10 と Iが結合して一つの字句要素になることはない。

「これが原因でNASAの宇宙ロケットが制御不能になり爆破された」という話が度々語られる。しかしこの話は、1960年代前半のほぼ同時期にあった、二つの異なった事件の混同による、ある種の「都市伝説」である。

要約すると、

FORTRANの言語仕様が原因で生じたバグは、実機ではなくソフトウェアだけでの実行結果の異常として発覚し修正されたため、実際のロケット打ち上げには関係していない。これはマーキュリー計画において起きた。
宇宙機のロストにつながったプログラムのミスは言語仕様とは関係なく、プログラムするべき、として示された数式において、必要な線が欠けていたため発生した。これはマリナー1号において起きた。プログラミングに間違いは無くても、要求された仕様の時点でその中にバグがあるかもしれない、という教訓となっている。DO文によるバグは、1963年、マーキュリー宇宙船の軌道計算ソフトウェアを開発中に、スタッフの一人が計算精度に問題があることに気づいた。コードを調査した結果、「DO 10 I=1.10」という行を発見した。それが原因で、ループにより近似の精度を高めるはずのコードが、ループしないため精度を高めることなく通り過ぎてしまっていた。これを「DO 10 I=1,10」と修正したところ、期待した精度が得られるようになった。

宇宙機の喪失につながった事故は、1962年、金星探査機マリナー1号を打ち上げるアトラスロケットには、Rate SystemおよびTrack Systemと呼ばれる二種類の制御系統が搭載されていた。Rate Systemは搭載型であり、地上型のTrack Systemは前者に対するバックアップとして動作する。1962年7月、マリナー1号の打ち上げ直後に、ロケットのguidanceアンテナは必要な性能を発揮しなくなり、搭載型システムのみに頼ってロケットは制御されることになった。しかし搭載型システムには次のような仕様バグがあった。「このようにプログラムすべき」として指示されていた手書きの数式中の、平均化を示す線が欠落しており、そのため平均化した値を使うべきところでそのままの値が使われ、微妙なタイミング差の平滑化処理に問題があった'//

3. 出典
-----

4. 参考文献
-------

[1]
[2]
浦昭二、近藤頌子、土居範久、原田賢一『FORTRAN 77入門』培風館、1982年

5. 関連項目
-------

FORTRAN
Fortranの言語仕様-
Co-array Fortran
High Performance Fortran