大信田 丈志
作成: 2000-10-23
まず言っておかなければならないことは、 FORTRANそのものは未だ生命を保っているかもしれないにせよ、FORTRAN77は既に過去の遺物であるということだ。 どうしてもFORTRAN系の言語を使うのなら、Fortran90に移行するか、 せめて GNU Fortran の拡張機能を利用して、 読みやすく、バグの少ないプログラムを書くようにすべきである。
GNU Fortran は、基本的にはFORTRAN77をベースにしているが、 それに加えて さまざまな拡張機能を取り込んでいる。 これらの拡張機能のなかには「Fortran90でも通用し、かつ 良いプログラムを書くのに役立つような機能」が少なくない。 そういう機能を積極的に利用すべきである。 具体的には、次のようなものが挙げられる:
私の手元にある版のg77.infoの内容を自分なりにまとめたもの。 内容が正しいかどうかは一切保証しないので、そのつもりで読んでほしい。 英語の文書を読むパワーと時間がある場合は、 自分のマシンのg77.infoを直接読むか、 本家GNUや Delorie Softwareのオンラインマニュアルを参照するほうが良いだろう。
% g77 -v Reading specs from /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.29/specs gcc version egcs-2.90.29 980515 (egcs-1.0.3 release) % locate libf2c /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.29/libf2c.a /usr/lib/libf2c.a % locate libf2c | xargs file # 両者の実体は同じであることが分かる g77 は gcc のフロントエンドであり、gcc が f771 を呼び出す: % locate f771 % g77 -v hello.F % g77 --driver=/bin/true # ← gcc を呼ぶのを邪魔する
% g77 -fno-silent hello.F # プログラム単位の名前をstderrに表示
% g77 -fno-ugly prog.F # 「醜悪な」構文をまとめて排除 (→ distensions)
-ff90 : Fortran 90 の構文(の一部)が認識できるようになる
-ffree-form または -fno-fixed-form : 自由形式
-fbackslash および -fno-backslash : たとえば '\n'を「改行」に変換するか否か
[デフォルトは -fbackslash]
-fcase-preserve : U と u を区別する(?)
-ffixed-line-length-桁数 : 固定形式での桁数の指定
-w : 警告メッセージを抑止
-Wimplicit : 各単位で IMPLICIT NONE を宣言するのとほぼ同じ
-Wall : -Wunused と -Wuninitialized を組み合わせたものと同等
-Wsurprising : 解釈に任意性がある式などの問題点を指摘する
-g : デバッグ情報を追加 (ただしまだ不完全) → -fdebug-kludge
-O : 最適化
-malign-double : [i386系(Pentiumなど)で倍精度を多用する場合に有効]
「GNU Fortran言語」 = ANSI FORTRAN 77 + GNU独自の拡張
厳密には「GNU Fortran言語」と g77 の仕様は一致しない.
「言語」の仕様に含まれない拡張機能の例:
現時点では大文字と小文字の区別に対応できていない.
感嘆符から行末まではコメント(ただし感嘆符が第6桁にある場合は継続行)
セミコロンで文を並べて書ける.
ただし, 次のように IF のあとにセミコロンを使うのは良くない:
IF (VALIDP) CALL FOO; CALL BAR
プログラム単位の末尾の「END」の代わりに「END PROGRAM」「END SUBROUTINE」
などと書くことができる.
INCLUDE 'ファイル名' が使える.
これは実行文でも非実行文でもない: statementではなく directiveである.
%LOC() %VAL() %REF() %DESCR()
※ 濫用厳禁! OSやウィンドウシステムなどにアクセスする部分に
限って使用し, プログラム本体での使用を避けるようにする.
× REAL(EXPR) ! 戻ってくる型が不明
○ REAL(REAL(EXPR)) ! REAL(KIND=1)が戻ってくる
○ REALPART(EXPR) ! EXPRの型に合わせて適切な実数型を返すFORTRANの主プログラム → 関数 MAIN__() としてコンパイルされる
副プログラムのコンパイル:
SUBROUTINE F(str) → void f_(char *str, ftnlen __g77_length_str)
CALL FOO('HI','THERE') → foo_("hi","there", 2,5);
※ 文字列の末尾に '\0' がつくことを期待してはならない.
共有ブロック: 今のところ, char配列として実装されている.
[例] COMMON I(15), R(20), T → char _BLNK__[144]
I → _BLNK__[0..59]
R → _BLNK__[60..139]
T → _BLNK__[140..143]
EQUIVALENCE: COMMONブロックを含む場合はCOMMONブロックと同じ方法で実装.
そうでない場合は __g77_equiv_X のような char配列として実装.
暗黙の型宣言を避ける:
変数の値がきちんと設定されていることを確かめる:
バッファへの書き出し: CALL FLUSH(N)
Pentium または Pentium Pro で次のように指定すると少し速くなる: -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -fomit-frame-pointer ただし -fomit-frame-pointer を指定するとデバッグができなくなる.