2

我有一个 FORTRAN 文件“testValueKeyword.for”包含以下代码

  subroutine intersub2(x,y)
    integer, value ::  x
    integer y
    x = x + y
    y = x*y
  print *, 'in subroutine after changing: ', x, y
  end subroutine

  program testValueKeyword
    integer :: x = 10, y = 20
    print *, 'before calling: ', x, y
    call intersub(x, y)
    print *, 'after calling: ', x, y
    x = 10
    y = 20
    call intersub2(x, y)
  contains
  subroutine intersub(x,y)
    integer, value ::  x
    integer y
    x = x + y
    y = x*y
    print *, 'in subroutine after changing: ', x, y
  end subroutine
  end program

子例程 intersub 和 intersub2 包含相同的代码,都通过值传递 x 参数,但 intersub2 似乎传递了一个类似于内存地址的大随机整数。运行后我得到不同的 y 值。你能给我解释一下吗?

4

2 回答 2

7

将子例程 intersub2 放入一个模块和use来自调用者的那个模块,这里是程序 testValueKeyword,以便调用者“知道”要使用的调用约定。当您在过程(子例程或函数)中使用 Fortran >=90 的“高级”参数功能时,您需要使接口对调用者显式,以便调用者使用与过程相同的接口/调用约定。否则调用者和被调用者之间的不一致将导致两者之间的“随机”通信。使接口为人所知的最简单方法是将过程放入一个模块和use该模块中。您也可以使用 来描述该过程interface,但这是更多的工作和需要维护的第二件事。

当我使用带有大量警告选项的 gfortran 编译您的代码时,gfortran 甚至会告诉我问题所在:

call intersub2(x, y)
                  1
Error: Dummy argument 'x' of procedure 'intersub2' at (1) has an attribute that requires an explicit interface for this procedure

如果您使用的是 gfortran,请尝试以下编译器选项进行调试:-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace

于 2013-09-30T18:11:14.877 回答
0

正如 MSB 所说,程序testValueKeyword不知道是什么intersub2,所以你得到垃圾数据也就不足为奇了。

作为 MSB 建议编写 a 的替代方法MODULE,您还可以放入程序intersub2CONTAINS一部分并获得正确的结果。

于 2013-09-30T18:15:23.040 回答