代码在一台计算机上运行并在另一台计算机上编译(没有警告和编译器错误),但是有运行时错误

时间:2016-04-08 15:35:24

标签: makefile fortran fortran90 gfortran

我在FORTRAN编写了一个程序,它是一个简单的乘法程序。它似乎在一台计算机上工作正常(编译没有警告和输出是正确的),但是当我将文件夹scp到另一台计算机时,它编译没有警告但是,输出更改为随机数,不知道为什么这是?有两个输出,一个是递归算法,另一个是迭代完成。递归工作正常,但迭代给出错误。我已经运行make clean,我也尝试将文件夹更改为一个新的干净文件夹,仍然是同样的问题。

它正常工作的版本:GNU Fortran(Debian 4.9.2-10)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

我还在计算机上收到以下警告:

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

对于上面的警告,我已经在原来的计算机和scp上做了干净,之后它似乎没有摆脱它。但是,当我清理它时,它不会再在该计算机上产生警告。我不确定为什么会这样。

1 个答案:

答案 0 :(得分:2)

itratvmultply

中的这一行
   itratvmultply = (multiplicand + itratvmultply)

首先执行结果变量(即itratvmultply)不保证具有任何特定值;它尚未明确分配给。这意味着赋值的 rhs 实际上是垃圾。

如果在一台计算机上(使用一个版本的编译器和一个未知的(对我们)编译选项集),您报告的症状是完全可解释的,编译器将值设置为0而在另一台计算机上(不同)编译器版本,可能是不同的选项)没有提供这样的值,变量可以获得恰好是位和字节的任何内容。

您可能认为编译器在程序启动时将变量设置为0。 Fortran语言标准无法保证这一点。低级优化的编译器通常会在程序启动时将变量设置为0,但在较高级别则不会。

要解决这个问题,请包括

 itratvmultply = 0

在代码第一次出现在赋值的 rhs 之前的代码中。并查看编译器的文档,了解如何使用它来警告您使用未初始化的变量。

@ TriskalJM的评论回答了你关于制作过程中有趣的未来主义的问题。