亲爱的Fortran程序员,
我对以下简单的fortran代码
的行为感到困惑 program foo
implicit double precision (a-h,p-w), integer*8(i-n),
+ character*12(x-z)
xx = 'not working '
call lskip(xx,4,8)
call lskip2(xx,4,8)
end
subroutine lskip(xxx,n,m)
implicit double precision (a-h,p-w), integer*8(i-n),
+ character*12(x-z)
print*, ' ine lskip ',xxx,n,m
return
end
subroutine lskip2(xxx,n,m)
character*(*) xxx
print*, ' ine lskip2 ',xxx,n,m
return
end
用gfortran-4.2.1
打印如下内容。
ine lskip not working 7308894831428763652 17179869192
ine lskip2 not working 4 8
并且使用intel的ifort-12.1.2
输出看起来像;
ine lskip not working 34359738372 8
ine lskip2 not working 4 8
subroutine lskip()
有什么问题?为什么我不能在这种情况下再次使用implicit declaration
?
答案 0 :(得分:2)
编译器没有抛出警告,但是你传递了错误精度的整数文字:
call lskip(xx,4,8)
子例程lskip
期望参数为integer*8
,而4和8的默认精度为integer*4
。
在这种情况下正确的电话可能是
call lskip(xx, 4_8, 8_8)
但是,除非这是传递给您的遗留代码,否则我强烈建议避免以此样式编写任何代码,即Fortran 77(固定格式源代码,无模块)。特别是,由于程序不再需要打卡,不使用隐式打字任何地方,因为它是许多邪恶的来源。
因此,一个好习惯是将它放在程序的父范围内:
implicit none
答案 1 :(得分:1)
添加到现有答案...如果编写程序以使用Fortran 90的功能,编译器将自动找到问题。通过程序中的子例程和模块use
d,编译器将检查参数的一致性。从FORTRAN 77切换到Fortran 90的众多原因之一。
快速转换为Fortran 90:
module MyStuff
contains
subroutine lskip(xxx,n,m)
implicit double precision (a-h,p-w), integer*8(i-n), character*12(x-z)
print*, ' ine lskip ',xxx,n,m
return
end
subroutine lskip2(xxx,n,m)
character*(*) xxx
print*, ' ine lskip2 ',xxx,n,m
return
end
end module MyStuff
program foo
use MyStuff
implicit double precision (a-h,p-w), integer*8(i-n), character*12(x-z)
xx = 'not working '
call lskip(xx,4,8)
call lskip2(xx,4,8)
end
这种转换并没有消除隐式输入,我完全同意不应该使用它。
在编译这个版本时,gfortran 4.9说:
MyStuff.f90:22.17:
call lskip(xx,4,8)
1
Error: Type mismatch in argument 'n' at (1); passed INTEGER(4) to INTEGER(8)
答案 2 :(得分:0)
您正在将默认类型整数(通常为integer*4
)传递给integer*8
,因此整数的表示形式不匹配,从而导致垃圾。
在第二种情况下,您也在子例程中使用默认整数,因此一切都按预期进行。如果您在主程序中使用变量来保存第一个和第二个参数的值,则值将转换为指定的种类:
i1 = 4
i2 = 8
call lskip(xx,i1,i2)