Fortran将数字传递给子程序

时间:2014-06-25 10:06:33

标签: fortran gfortran intel-fortran

亲爱的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

3 个答案:

答案 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)