Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture Aliasing in Subroutine

Tags:

fortran

Is there a way to check whether aliasing occurs in a Fortran subroutine, or at least to tell the compiler to issue a warning?

Consider this (rather simplistic) example:

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

Here, the result is set to zero in the subroutine. If the same variable is given as input and output, the result is (obviously) wrong. Is there a way to capture this kind of aliasing at run-time or at compile-time?

like image 204
Alexander Vogt Avatar asked May 16 '14 15:05

Alexander Vogt


2 Answers

Yes, gfortran will detect some aliasing with the compiler option -Waliasing, however, the arguments must have intents in and out. It won't work with your example because you have declared argument c as intent(inout). In this example you can simply change the intent to out since the input value of c is not used. They try the compiler option! gfortran outputs:

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)
like image 170
M. S. B. Avatar answered Oct 10 '22 20:10

M. S. B.


I don't know of options in g95 or gfortran to detect the aliasing error at compile or run time. The programmer is responsible for avoiding such an error. You can pass the intent(in) arguments as expressions to ensure that they are not changed within the subroutine, as shown below.

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
like image 23
Fortranner Avatar answered Oct 10 '22 19:10

Fortranner