在子程序中捕获别名

时间:2014-05-16 15:37:19

标签: fortran

有没有办法检查Fortran子例程中是否出现别名,或者至少告诉编译器发出警告?

考虑这个(相当简单)的例子:

module alias
contains
  subroutine myAdd(a, b, c)
    integer,intent(in)    :: a, b
    integer,intent(inout) :: c

    c = 0
    c = a + b
  end subroutine
end module

program test
  use alias
  integer :: a, b

  a = 1 ; b = 2
  call myAdd(a, b, b)
  print *, b, 'is not 3'
end program

这里,结果在子程序中设置为零。如果给出相同的变量作为输入和输出,结果(显然)是错误的。有没有办法在运行时或编译时捕获这种别名?

2 个答案:

答案 0 :(得分:5)

是的,gfortran将使用编译器选项-Waliasing检测到一些别名,但是,参数必须具有意图inout。它不会使用您的示例,因为您已将参数c声明为intent(inout)。在此示例中,您只需将意图更改为out,因为未使用c的输入值。他们尝试编译选项! gfortran输出:

alias.f90:17.16:

  call myAdd(a, b, b)
                1
Warning: Same actual argument associated with INTENT(IN) argument 'b' and INTENT(OUT) argument 'c' at (1)

答案 1 :(得分:3)

我不知道g95或gfortran中的选项可以在编译或运行时检测别名错误。程序员负责避免这样的错误。您可以将intent(in)参数作为表达式传递,以确保它们不会在子例程中更改,如下所示。

module alias
contains
  subroutine myAdd(a, b, c)
    integer,intent(in)    :: a, b
    integer,intent(inout) :: c
    c = 0
    c = a + b
  end subroutine myadd
end module alias

program test
  use alias, only: myadd
  integer :: a, b
  a = 1 ; b = 2
  call myAdd((a),(b),b) ! parentheses around arguments a and b
  print*, b,"is 3"
  call myAdd(a, b, b)
  print*, b,"is not 3"
end program test