• 締切済み
  • 困ってます

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

以下のような短いフォートランプログラムがあります。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が一番近いと思いましてこちらに上げました。

共感・応援の気持ちを伝えよう!

  • 回答数5
  • 閲覧数63
  • ありがとう数4

みんなの回答

  • 回答No.5
  • asciiz
  • ベストアンサー率71% (5193/7235)

回答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)等)などをモジュール名に使っても、何も問題ないでしょう。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • 最新のgfortranでのコンパイルエラー

    GNU Fortran (Rev1, Built by MSYS2 project) 9.3.0ですが、現時点での最新バージョンと思われます。以下のソースファイルをコンパイルしてみました。 module abc real x,y end module abc program test use abc x=3.14 y=5.55 print *, x,y call xxx print *, x,y end program test subroutine xxx use abc x=5.55 y=3.14 end subroutine xxx その結果、 f951.exe: Fatal Error: Reading module 'abc' at line 1 column 46: Unexpected EOF というエラーになります。 10年以上前のintel fortranだと問題なくコンパイルでき結果もOKです。 できれば新しいコンパイラを使いたいのですが、ソースをどのように改変していけばいいでしょうか。また、最新版のコンパイラをやめた方がいいのでしょうか。コンパイラを新しくして他にもトラブルが出ているのですが。 Cのカテゴリですみません。ここしか思い当たらないので。

  • フォートランのサブルーチンの内部変数

    すみません。科学技術系の人間でして、フォートランが現役なのです。 あるプログラムのことですが、サブルーチンの内部の変数についてサブルーチンを呼び出すごとに加算していくようなことを行っています。 do i=1,100 call abc(i)   ← サブルーチンabcを100回呼び出す enddo end subroutine abc(i) n=n+1        ←呼び出されるたびに和をとる。 write(*,*) n return end このようなシンプルなプログラムは問題ないのですが、少し複雑になるとどういうわけか、呼び出される度にnが初期化され、writeさせた結果常に1が表示されるという現象に会いました。 昔のコンパックフォートラン(MS-Fortran, DEC Fortranを継承)と、最近のIntel Fortran(最新版)で動作が異なります。前者では和を取ってくれますが、後者では初期化されて常に1が出力されます。(上記のプログラムは問題なしです。もう少し長いプログラムでの問題です。) 言語仕様の問題(すなわちフォートランのバージョン)なのか、コンパイラ仕様の問題なのか、C言語のように宣言の仕方で変ったりするようになったというようなことはないでしょうか。 以下に示すように和をとる変数をメインプログラム側に一旦見えるようにすると、インテル版でも思ったとおりの動作をします。 call abc(i,n) suboroutine abc(i,n) としてnをメイン側に露出する。 よろしくお願いします。

  • 64ビットPCでのフォートランコンパイラ

    仕事柄いまだにフォートランのプログラムソースを書いています。物理シミュレーションを行っており、計算機の高速化に期待しているところです。地球シミュレータなどのメインフレーム?ではなく、高速のパソコンでも仕事ができるような程度のものです。 さて、質問ですが、最近、64ビットPC機、64ビット対応OSが手ごろな価格でも出ています。ノートPCでさえ8メガのメモリを積んでいるようです。この場合、フォートランコンパイラについても64ビット対応である必要があるのでしょうか。インテル、Visual Fortran, FTN95, G95, Gfortranなど有償・無償いろいろあると思います。64ビットOS用のコンパイラがあるのでしょうか。それとも従来の32ビット版でも十分な計算速度が出るでしょうか。よろしくお願いします。

  • 回答No.4
  • asciiz
  • ベストアンサー率71% (5193/7235)

>モジュール名は固有名なので常識の範囲で何でもアリだと思っていました。 基本的に何でもアリだと思うんですが、コンパイルしたときに「モジュールファイル」みたいなものができていないでしょうか? 例えば、「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 とか指定しても何の問題もないでしょうね。(使ったことありませんが!)

共感・感謝の気持ちを伝えよう!

  • 回答No.3
  • sat000
  • ベストアンサー率37% (249/663)

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は不要になりました。あってもエラーにはなりませんが。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

回答ありがとうございます。これは自由形式で書いています。fortran95の仕様です。以前のfortran77の形式に慣れていましたが、95の形式に移行しています。拡張子はf95です。 モジュール、メイン、サブルーチンの閉じ方についてはやり方に幅があるようです。 また、いけるコンパイラといけないコンパイラがある、というところで戸惑っています。intel はいけています。ただし、やや古いので拡張子はf95でなく、f90にしています。拡張子だけが違うものです。

  • 回答No.2

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

  • 回答No.1
  • asciiz
  • ベストアンサー率71% (5193/7235)

「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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

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

関連するQ&A

  • 隔絶されているサブルーチン間の通信の方法

    以下のようなFortranのサブルーチンとモジュールがあります。これを見ると、サブルーチンA,Bはモジュールa,bが別なのでデータ的に隔絶されていることになります。もし、このような場合、サブルーチンA,Bの間で何らかの変数を共有するようなことをしたい場合、どのような方法があるでしょうか。サブルーチンの引数を使うのは混乱の原因になりそうなので、できればmoduleの方で処理できないかと思うのですが。 混乱しそうなところなので、やり方をいろいろ比較して見てみたいと思います。Cではグローバル変数のように全体で共有する変数を用意するのかなと思いますが。 module a end module module b end module subroutine A use a end subroutin B use b end Fortranについてはここでは特設会議室はありませんが、どこかいいところがあるでしょうか。Cの専門家はいろんなことに通じていると思うのでここにお尋ねしました。よろしくお願いします。

  • Fortranについて教えてください

    Fortran90で書かれた、又はこれから書く、プログラム実行したく GCCのgfortranをインストールしました。OSは、Windows XPです。 ところが、コンパイルのところで、つまずいてなかなか進みません。 (gfortranは動いてますので、インストールに問題はないと思います。) そこで、gfortranについて(オプション等)、解説しているサイトや文献を教えて頂きたいと思います。 英語力があまり無いので、日本語のものを紹介いただけると助かります。 また、十数年ぶりのフォートランですので(現在はVBAしか触っていません)、初学者向けだと、なお助かります。 どうか、よろしくお願いします。

  • fortran subroutineについて

    fortran subroutineについて c c c kk.f c c integer a,b a=0 do 10 b=1,9,2 a=a+1 print * ,a 10 continue write(*,*) ,'No.1' call sub(a,b) stop end c subroutine sub(a,b) write(*,*) ,'No.2' return end  簡単に上記のようにつくってg77でコンパイルしたのですが、call文とsubroutine文の部分で警告が出ました。  実行ファイルは問題なく動作をするのですが、このままでもいいのでしょうか?ちなみに、警告文を読んでも僕には理解できませんでした。  以下、警告文です。 kk.f: In subroutine `sub': kk.f:13: warning: call sub(a,b) 1 kk.f:17: (continued): subroutine sub(a,b) 2 Argument #1 (named `a') of `sub' is one type at (2) but is some other type at (1) [info -f g77 M GLOBALS] kk.f:13: warning: call sub(a,b) 1 kk.f:17: (continued): subroutine sub(a,b) 2 Argument #2 (named `b') of `sub' is one type at (2) but is some other type at (1) [info -f g77 M GLOBALS]

  • fortran 実行結果がうまく表示されない

    グローバルモジュールを用いてプログラムを書いたのですが実行結果が表示されません、プログラム中に問題があるのでしょうか?教えて下さい。 module params implicit none integer :: n = 2 end module params module sample implicit none contains subroutine swapvec3(x,y) use params real(8), intent(inout) :: x(n), y(n) real(8) tmp(n) tmp(1:n) = x(1:n) x(1:n) = y(1:n) y(1:n) = tmp(1:n) end subroutine swapvec3 end module sample program main use sample implicit none real(8), allocatable :: a(:), b(:), tmp(:) integer n allocate(a(n),b(n),tmp(n)) call swapvec3(a,b) call random_seed call random_number(a) call random_number(b) call random_number(tmp) write(*,*) ' a = ', a(1:n) write(*,*) ' b = ', b(1:n) write(*,*) ' tmp = ', tmp(1:n) end program main 実行結果  a = b = tmp =

  • fortran77教えてください

    fortran77のプログラムについての質問です。 次のプログラムを実行するとどのような結果になるか教えてください REAL A,B,C,D,E,F A=7.0 B=5.0 CALL WASA(A,B,C,D) CALL WASA(C,D,E,F) WRITE(*,*)E,F STOP END SUBROUTINE WASA(P,Q,R,S) REALP,Q,R,S R=P+Q S=P-Q RETURN END

  • 副プログラムの変数について

    Fortranなのですが、以下のようなプログラムがあります。 call sub1 call sub1 end subroutine sub1 !save a write(*,*) a a=1.0 return end sub1というサブルーチンをメインから2回呼び出すだけです。そのサブルーチンの中の変数aですが、2回目に呼び出されたときに1回目に設定したa=1が保持されているようです。2回目の呼び出しで1回目に設定したa=1に対応した出力になっています。 Fortranはこのような動作をするのでしょうか。save aをコメントアウトしているのです。save aを指定したときだけそうなると思っていたのですが。cなどは細々とした設定ができるだろうと思います。このサンプルコードは実際にそうなっているという実験なのですが、どういう風に解釈したらいいでしょうか。〇〇保存属性とかです。昔からこうだったのでしょうか。使用したのはgfortran ver.9.3ですが。 

  • Do文で副プログラムの増やす【Fortran】

    Fortranを使用してます。 DO文で副プログラムをループさせて増やしたいのですが、どうすればいいか分りません。 具体的には、副プログラムの「SUBROUTINE」文+サブルーチン名 であるサブルーチン名の後にループを使って番号を付けたいのですが・・・ 簡易なイメージとして以下のソースでtest0、test1、test2、・・・・・test10となるようなサブルーチン名にしたいのです。 do x=0,10 SUBROUTINE test+x y=x+10 retun end end do Fortran初心者ですが、解決したいので難しい解説でも大丈夫です。 分る方は宜しくお願いいたします。

  • メインルーチンの変数をモジュールに渡す

    Perlの勉強をし始めの者なんで、恥ずかしい質問ですけど・・・ モジュールの使い方です。 以下のプログラムではTest_module.pmで定義した変数$testをメインルーチンでprintしています。 ***** メインルーチン *****  #perl /usr/bin/perl  use Test_module;  our $test=10;  print $Test_module::test; ***** Test_module.pm *****  package Test_module;  our $test=10;  1; これはちゃんと動いています。 ところが逆にメインルーチンで定義した変数$testをTest_module.pmに渡そうとすると、うまくいきません。 以下のプログラムをどう直せばいいのでしょうか。 ***** メインルーチン *****  #perl /usr/bin/perl  use Test_module;  our $test=10;  &Test_module::print_test(); ***** Test_module.pm *****  package Test_module;  sub print_test {  print $Main::test;  }  1;

    • ベストアンサー
    • Perl
  • Fortran90についての質問です。

    Fortran90に関する問題です。 「正の整数mを正の整数nで割った余りrを求める手順を、組み込み関数MOD(m,n)を用いずに、単一の算術式で表せ」 このプログラム文を以下のように作成しました。ファイル名は「amari.f90」にしました。 INTEGER::m,n,f,r REAL::a,k PRINT*,'Input 正の整数' READ*,m,n a=REAL(m) k=a/n f=INT(k) IF(m>0,n>0) THEN r=m-(f*n) PRINT*,'余り=',r END IF END そして、Cygwin画面上で gfortran -o amari.exe amari.f90と打って、コンパイルしようとしたら以下のようなエラー文が出ました。 amari.f90:8.6: IF(m>0,n>0) THEN 1 Error: Syntax error in IF-expression at (1) amari.f90:11.3: END IF 1 Error: Expecting END PROGRAM statement at (1) プログラム文のどこの箇所が間違っているのかを教えていただけませんか?お願いします。

  • Fortran "実引数の型が仮引数の型と異なります。"

    Fortran "実引数の型が仮引数の型と異なります。" Intel Visual Fortranの最新版をMS Visual Studio 2008で使用(お試し)しています。 既存のFortranプログラムでエラーが出て、使えなくなりました。 問題点を要約すると以下のようなシンプルなコードに集約されました。 ---------------------- 00 program main 01 call sub1(10.d0) 02 call sub1(10.0) 03 end ! ---------------------- 04 subroutine sub1(rr) 05 real*8 rr 06 write(*,*) 'rr = ', rr 07 end subroutine ! --------------------- 昔のFortranでは、Subをcallする時に、仮引数の型と厳密に一致していなくても、うまく処理してくれたと思います。(倍精度でも整数でも、同じ数値とみなして) オプションのルーチンインターフェースのチェック(/warn:interfaces)をオフにすると、コンパイルは出来るようになるのですが、上記プログラムの計算結果は、01行と02行で結果が異なってきます。 (02行はおかしな値が入る) 本来、ランタイムエラー防止の観点からは、このような厳密性を要求するのは良いことだと思いますが、既存のプログラムが実行できなくなるのは痛手なので、何かオプションの変更で対応出来ないものでしょうか? よろしくお願いいたします。