Alexander Vogt
Alexander Vogt

Reputation: 18118

Capture Aliasing in Subroutine

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?

Upvotes: 5

Views: 416

Answers (2)

M. S. B.
M. S. B.

Reputation: 29401

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)

Upvotes: 7

Fortranner
Fortranner

Reputation: 2605

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

Upvotes: 3

Related Questions