Context
The toy Fortran code posted below calls two pointer functions. That is, both functions return a pointer. In fact, they're both array pointers. They both attempt to do the same thing, which is to return an integer array pointer referencing an integer array having three elements, 1, 2, and 3. The first function uses the pointer assignment operator (=>) to point the function pointer to an allocatable array that holds the data. The second function allocates a block of dynamic memory directly, via the pointer, for storing the data. The calling program just prints the elements of the returned array(s).
Here's what I find odd.
- If I point
a
to the result offunction1
, the results are not correct. The first element ofa
appears to be "clobbered":a
has0
,2
,3
. - If I point
b
to the result offunction2
, the results are correct.b
gets1
,2
,3
. - Stranger still, pointing
b
to the result offunction2
after pointinga
tofunction1
changesa
such that it becomes correct.a
then has1
,2
,3
.
Question
Why does this occur? More precisely, why does a pointer function that returns a pointer to an allocatable array clobber the first element of that array for the caller? More precisely still, why does pointing one pointer (b
) produce a side-effect on another pointer (a
), where the targets come from different functions that are written so as not to interact with each other at all?
Caveats
I get this behavior using the GNU Fortran compiler v.4.3.3, running an Intel laptop with Ubuntu (Jaunty). Your results may vary, which might be more interesting still. Finally, as always it could be operator error on my part, which would be interesting to me at least.
Code
program main
implicit none
integer, dimension(:), pointer :: a, b
integer :: i
a => function1()
b => function2()
do i = 1, 3
print *, a(i)
end do
! do i = 1, 3
! print *, b(i)
! end do
contains
function function1 ()
integer, dimension(:), allocatable, target :: array
integer, dimension(:), pointer :: function1
allocate(array(3))
array(1) = 1
array(2) = 2
array(3) = 3
function1 => array
end function function1
function function2 ()
integer, dimension(:), pointer :: function2
allocate(function2(3))
function2(1) = 1
function2(2) = 2
function2(3) = 3
end function function2
end program main