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

Makefile 代码在一台计算机上工作,并在另一台计算机上编译(没有警告和编译器错误),但有运行时错误,makefile,fortran,fortran90,gfortran,Makefile,Fortran,Fortran90,Gfortran,我用FORTRAN编写了一个程序,它是一个简单的乘法程序。它似乎在一台计算机上运行良好(编译时没有警告,输出正确),但当我将文件夹scp到另一台计算机上时,它在没有警告的情况下编译良好。但是,输出变为随机数,不确定这是为什么?有两个输出,一个是递归算法,另一个是迭代完成的。递归可以很好地工作,但迭代会产生错误。我已经运行了makeclean,我还尝试将该文件夹更改为一个新的clean文件夹,仍然存在相同的问题 它可以正常工作的版本:GNU Fortran(Debian 4.9.2-10)4.9.

我用FORTRAN编写了一个程序,它是一个简单的乘法程序。它似乎在一台计算机上运行良好(编译时没有警告,输出正确),但当我将文件夹scp到另一台计算机上时,它在没有警告的情况下编译良好。但是,输出变为随机数,不确定这是为什么?有两个输出,一个是递归算法,另一个是迭代完成的。递归可以很好地工作,但迭代会产生错误。我已经运行了makeclean,我还尝试将该文件夹更改为一个新的clean文件夹,仍然存在相同的问题

它可以正常工作的版本:GNU Fortran(Debian 4.9.2-10)4.9.2

输出错误的版本:GNU Fortran(Debian 4.4.5-8)4.4.5

我还收到计算机上的以下警告,表明它不工作:

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

对于上面的警告,我已经在原来的计算机和scp上进行了清理,之后,它似乎没有摆脱它。然而,当我清理时,它不会在那台计算机上再次产生警告。我不知道这是为什么

当该行位于
itratvmultply

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

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

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

要解决此问题,请包括该行

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


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

当这行出现在
itratvmultply

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

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

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

要解决此问题,请包括该行

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


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

为什么当
整数(li)
li
一起定义时,整数(kind=8)又长又丑呢?(将
li
重命名为您想要的任何名称…)在gfortran 4.9上使用
-fsanize=address,未定义的
,编译器应该会抱怨。Valgrind也应该抱怨。您会收到警告,因为原始机器上的系统时钟早于第二台机器。因为make是缓存的,所以您必须在第二台机器上执行
make clean
,以便
make
生成的文件使用第二台机器的时钟进行时间戳。说了这么多,我不认为这是你的问题所在。为什么
integer(kind=8)
这么长又难看,而
integer(li)
li
一起定义的某个地方更好(更短)?(将
li
重命名为您想要的任何名称…)在gfortran 4.9上使用
-fsanize=address,未定义的
,编译器应该会抱怨。Valgrind也应该抱怨。您会收到警告,因为原始机器上的系统时钟早于第二台机器。因为make是缓存的,所以您必须在第二台机器上执行
make clean
,以便
make
生成的文件使用第二台机器的时钟进行时间戳。说了这么多,我不认为这是你的问题所在。