こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

フォートランの動作に関する質問

以下のような短いフォートランプログラムがあります。OS:Windows10

module com
integer,parameter ::nd=10
end module

program main
use com

print *, nd

call sub

stop
end

subroutine sub
use com
print *, nd
return
end

内容はモジュールで宣言したパラメータを確認してみるということです。
このプログラムがgfortranで動作せず、intel fortranでは全く問題ありません。

gfortranの結果は以下のようです。
f951.exe: Fatal Error: Reading module 'com' at line 1 column 1: Unexpected EOF

GNU Fortran (Rev1, Built by MSYS2 project) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.

gfortranのこのバージョンに何か問題があるのでしょうか。前からすこしおかしいことには気づいていたのですが。私のコードに問題があるでしょうか。
※Cが一番近いと思いましてこちらに上げました。

投稿日時 - 2020-10-18 16:21:51

QNo.9812780

困ってます

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

回答no.1に少し間違いがありました
「特殊ファイル名」として挙げたリストのうち、「COM0」「LPT0」は特殊ファイル名ではありませんでした。

>(※1)実際には、特殊ファイル名をベースネームとするファイルは作成できないはずです。

この回答No.4の一文を書いた後に実験したんですが、実際に "com0.txt" も "com.txt" も作成できます。
でも "com1.txt" は作成できません。
「COM1」は確かに特殊ファイル名です。

だとすると、ここから想像になりますが、

・GNU Fortranにおいて「module abc」というような記述をしたとき、「ABCx(xは1以上の数値).拡張子」というようなファイルが作成される
・それがたまたま「module com」により「COM1.拡張子」というファイル名を作成することになってしまった。
・それをコンパイル別段階で読み込もうとして、シリアルポート入力になってしまった。

こういうことであったかも…?

でもやはりこの「特殊ファイル名」がまずいんでしょうから、command.com の内部コマンド名(例:「copy」「type」等)や、外部コマンドの名前(format(.exe)やconvert(.exe)等)などをモジュール名に使っても、何も問題ないでしょう。

投稿日時 - 2020-10-19 11:54:37

お礼

回答ありがとうございます。
module comm
integer :: x
end module
などとすると、gfortranではcomm.mdというバイナリファイルが出力されます。module comだったらcom.mdです。
プログラミングについては今回の例のようにシステムとかOSとかに気を使いつつプログラムの内部を編集していくのがプロだと思いますが、私のごときはプログラムだけに集中したいものだと思っています。絶対(に近い)信頼を確信するからこそプログラムの中身だけに入っていけるわけですね。変数名の付け方でアウトになる可能性があり、そのことに気を使わなければならないというのは本職の方に集中できないなあという気持ちはあります。

投稿日時 - 2020-10-19 23:13:45

ANo.4

>モジュール名は固有名なので常識の範囲で何でもアリだと思っていました。

基本的に何でもアリだと思うんですが、コンパイルしたときに「モジュールファイル」みたいなものができていないでしょうか?
例えば、「module abc」と書いたなら、コンパイルの過程で「abc.module」みたいなファイルができているとか。
(一時的に作成されて、最終プログラム完成時点では残ってない、とかだと見えないですけど…)

仮にそうだったとして、「module com」という記述から、「C:\Fortran\COM.module」みたいなファイルが出来ていたとすると、(※1)
回答No.1に書いたMS-DOS特殊ファイル名は、どのようなフォルダにあっても・どのような拡張子がついていても、特殊ファイル(デバイスファイル)として動作してしまいます。
そしてコンパイルの別段階で「COM.module」ファイルを読み取ろうとしても、そこではシリアルから読み取ろうとしてしまい、ご質問のエラーが出てしまった、ということあるかもしれません (だとすると回答No.1の指摘も微妙に間違ってるかも…)。

(※1)実際には、特殊ファイル名をベースネームとするファイルは作成できないはずです。

----

まあ実際リネームで直ったっということですので、「com」というモジュール名が使えないのは、『コンパイラの実装方式』と『OSの都合』という【言語仕様外の話】で、ホントにたまたま都合の悪いモジュール名を使ってしまった、ということになりますかね…。

unix系のOSであれば、デバイスファイルは必ず /dev/console とか /dev/ttyS0 みたいに /dev/ 特殊フォルダからの指定が必須になるので、普通にcon.txt でも com.module でもファイル作成できます。
汎用コンピュータ上のFortranでも COM とか指定しても何の問題もないでしょうね。(使ったことありませんが!)

投稿日時 - 2020-10-19 11:29:02

ANo.3

1行目の1カラムに問題ありということを示しています。
ひょっとして7カラムからでなく、1カラムから書いてますか?
1カラムから書く場合は自由形式でないといけません。
GNU Fortran の場合は拡張子で判断するので、拡張子をf90やf95などとする必要があります。固定形式の場合はfやforにします。
あと今回のエラーとは関係ありませんが、end module -> end module comと書かないとコンパイルエラーになるかもしれません。
あと、mainのend -> end program main、subのところもend subroutine subですね。
それから、stopは不要になりました。あってもエラーにはなりませんが。

投稿日時 - 2020-10-18 18:07:45

お礼

回答ありがとうございます。これは自由形式で書いています。fortran95の仕様です。以前のfortran77の形式に慣れていましたが、95の形式に移行しています。拡張子はf95です。

モジュール、メイン、サブルーチンの閉じ方についてはやり方に幅があるようです。

また、いけるコンパイラといけないコンパイラがある、というところで戸惑っています。intel はいけています。ただし、やや古いので拡張子はf95でなく、f90にしています。拡張子だけが違うものです。

投稿日時 - 2020-10-18 18:56:22

ANo.2

昔のプログラマですが、今のフォートラン(Fortran)は我々の頃とまったく違うのですね。Fortranは”formula translation”の略称で数式の機械語への変換を行うコンパイラでした。お示しのプログラム例はそれとまったく異なる記述様式です。驚きました。単なる感想で、回答にならなくて済みません。

投稿日時 - 2020-10-18 17:57:13

お礼

コメントありがとうございます。自由形式になるとか、構造体やポインタがあるとか、C言語みたいです。
Cよりfortranがいいのはあんまり方言がないこととかバージョンアップして仕様が変わるとかが少なく、上位互換って言うんでしょうか、仕様が変わっても古いものが見捨てられないというのがありますね。F77の古いコードがF95のコンパイラで動作していました。今回の質問はコンパイラが変わっていける・いけないの差が出てきたということでフォートランの利点が損なわれたように思えたからなのですが。

投稿日時 - 2020-10-18 19:01:00

ANo.1

「COM」という名前を使う必要はありますか?

common とか command とかの省略のつもりだったでしょうか?

と言うのも、Windowsでは、デバイスを表す特殊ファイル名というのが存在します。MS-DOS時代(以前)からの遺産です。
コンソール(キーボード)入力を示す CON だとか、プリンタ出力を表す PRNなど。
そういう予約ファイル名の中に、COM0~COM9 と言う物が存在します。

厳密に言えば COM は COM0 ではないので、intel Fortran ではきちんと通るのかもしれません。
しかしgFortranの方では、COM=COM0のことだ、と解釈して、モジュールの com ではなく シリアルポートの COM0 からの読み込みを行おうとしてしまい、EOFに到達した(何も読めなかった)、と言うエラーが出てしまっているのかもしれません。

モジュール名を com 以外の物にしてみるとどうでしょう。
もちろん、次のような予約ファイル名と一致してはいけません。

予約ファイル名: CON, PRN, AUX, NUL, CLOCK$, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9

投稿日時 - 2020-10-18 16:43:25

お礼

回答ありがとうございます。それが正解でした。リネームで通りました。シリアルポートのあのCOMと解釈していたようです。モジュール名は固有名なので常識の範囲で何でもアリだと思っていました。ファイル名として使えないのはコマンド名とか組み込み関数名とかでしょうか。
また、intel fortranは通るというのはどうしたわけだろうと思いますが。また予約語であってもコンパイラがよきに取り計らうということはないのでしょうか。JavaとかC++
などは使い方(でてくる場面)に依存して解釈してくれるようですが。オーバー〇〇とかですかね。ロードとかライドとか。

投稿日時 - 2020-10-18 19:11:04

あなたにオススメの質問