Referencing Overlapping Arrays with Pointers

I need to perform a memmove()

-style operation with pointers set to overlapping arrays. More precisely, I need to copy b(:)

to a(:)

.

Pointers aliasing illustration

In the C programming language, I would call memmove(a, b, N)

. But as far as I know, the Fortran Standard is very strict when it comes to pointer aliasing.

So which of the following three options is safe to use (according to the standard) and which will result in undefined behavior:

  • vector syntax with aliased pointers (option 1),
  • an explicit do-loop with aliases (option 2),
  • a call to a procedure that takes overlapping arrays as arguments (option 3)

?

program ptr
  implicit none
  integer, parameter :: ARRAY_SIZE = 10, N = 6
  integer, target :: array(ARRAY_SIZE)
  integer, dimension(:), pointer :: a, b
  integer :: i

  a => array(1: N)
  b => array(3: N+2)

  ! Option 1
  a(1: N) = b(1: N)

  ! Option 2
  do i = 1, N
    a(i) = b(i)
  end do

  ! Option 3
  call foobar(a, b, N)

  contains

    subroutine foobar(a, b, length)
      integer, dimension(:), intent(out) :: a
      integer, dimension(:), intent(in) :: b
      integer, intent(in) :: length

      a(1: length) = b(1: length)
    end subroutine foobar
end program ptr

      

+3


source to share


1 answer


Parameters 1 and 2 are ok, the compiler knows that pointers can be aliased.

The subroutine is fine on its own, but you cannot pass two alias arguments there, which is indeed contrary to the standard (undefined behavior is a C term). You can make arguments pointer

, then anti-aliasing is possible and the program will conform as standard.



  integer, dimension(:), pointer :: a
  integer, dimension(:), pointer :: b

      

I also removed the intents because they refer to the association status of the pointer, not the target value as IanH commented. They also require Fortran2003.

+3


source







All Articles