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(:)
.
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
source to share
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.
source to share