2016-04-08 9 views
1

私はFORTRANでプログラムを作成しました。 1つのコンピュータで問題なく動作しているようです(警告は出力されず、出力は正しい)が、フォルダを別のコンピュータにscpすると警告なしで問題なくコンパイルされますが、出力は乱数に変わります。 2つの出力があります.1つは再帰アルゴリズムで、もう1つは繰り返し実行されます。再帰はうまくいくが反復はエラーを返す。私はmake cleanを実行しましたが、私はまた、同じ問題を解決して新しいフォルダに変更しようとしました。コードは1台のコンピュータで動作し、別のマシンで(警告およびコンパイラエラーなし)コンパイルしますが、実行時エラーがあります

それは上の正常に動作1のバージョン:GNU Fortranの(Debianの4.9.2-10)間違った出力と1の4.9.2

バージョン:GNU Fortranの(Debianの4.4.5-8)4.4。 5

program multiplication 

    integer(kind = 8) :: multiplier, multiplicand, rcursvmultply, itratvmultply 

    write(*,*) "multiplier?" 
    read(*,*) multiplier 

    write(*,*) "multiplicand?" 
    read(*,*) multiplicand 

    write(*,*) rcursvmultply(multiplier, multiplicand) 

    write(*,*) itratvmultply(multiplier, multiplicand) 
end program 

recursive function rcursvmultply(multiplier, multiplicand) result(answer) 

    integer(kind = 8), intent(in) :: multiplier, multiplicand 
    integer(kind = 8) :: answer 

    if (multiplier == 0) then 
     answer = 0 
    else if (multiplier == 1) then 
     answer = multiplicand 
    else if ((multiplier > 1) .and. (mod(multiplier, 2) == 0)) then 
     answer = rcursvmultply((multiplier/2), (multiplicand*2)) 
    else if ((multiplier > 1) .and. (mod(multiplier, 2) == 1)) then 
     answer = (multiplicand + (rcursvmultply((multiplier/2), (multiplicand*2)))) 
    end if 
end function rcursvmultply 

integer(kind = 8) function itratvmultply(multiplier, multiplicand) 

    integer(kind = 8) :: multiplier, multiplicand 

    do while (multiplier > 0) 
     if ((mod(multiplier, 2)) == 1) then 
      itratvmultply = (multiplicand + itratvmultply) 
     end if 
     multiplier = multiplier/2 
     multiplicand = multiplicand*2 
    end do 
end function itratvmultply 

私もそれが働いていないコンピュータ上で次の警告を得る:私はそれはdoesnの、その後元のコンピュータとscpにきれいな作りまし上記の警告については

make: Warning: File `Makefile' has modification time 4.6 s in the future 
make: warning: Clock skew detected. Your build may be incomplete. 

を〜するように見えるそれを取り除く。しかし、私がきれいにすると、そのコンピュータで再び警告が出ることはありません。なぜこのことが分かりませんか?

+0

'整数(li)'と 'li'がどこかで定義されているときに、とても長くて醜い' integer(kind = 8) 'がなぜとても優れていますか? ( '' li''をあなたの望むものにリネームします) –

+0

gfortran 4.9では、 '-fsanitize = address、undefined'を使用し、コンパイラは文句を言うべきです。 Valgrindも文句を言わなければならない。 –

+1

元のマシンのシステムクロックが2番目のマシンよりも早いため、警告が表示されます。makeはキャッシュされているので、第2のマシンで 'make clean'を実行する必要があります。そのため、' make'が生成するファイルには、第2のマシンの時計でタイムスタンプが付きます。 すべてのことを言っているが、私はあなたが持っている問題だとは思わない。 – TriskalJM

答えて

2

itratvmultply

itratvmultply = (multiplicand + itratvmultply) 

でこの行は、結果変数(すなわちitratvmultply)は、任意の特定の値を持つことが保証されていない最初に実行されると、明示的に割り当てられていません。つまり、割り当てのrhsは、事実上、ジャンクです。

コンパイラのバージョンと不明なコンパイルオプションの組み合わせを使用している場合、コンパイラは値を0に設定しますが、別のコンピュータ(異なるコンパイラバージョン、おそらく異なるオプション)、そのような値は提供されず、変数はビットとバイトがどんなものであっても取得します。

おそらく、プログラムの起動時にコンパイラが変数を0に設定していると思うかもしれません。これはFortran言語標準では保証されていません。そして、低レベルの最適化を行っているコンパイラは、プログラムの起動時に変数を0に設定するのが一般的ですが、より高いレベルではそうではありません。これは前の変数がRHS代入のに最初に表示するときに、あなたのコード内の

itratvmultply = 0 

行を含め固定するために

。そして、コンパイラーのドキュメントをチェックして、初期化されていない変数の使用について警告する方法を調べてください。

@ TriskalJMのコメントは、メイクプロセスにおける面白い未来主義についてのあなたの質問に答えます。

関連する問題