Yes, it was a problem due to the c_f_pointer restriction. As you have discovered, the built-in c_f_pointer only supports borders starting with index 1. People often claim that Fortran is an indexed language, but this is not so. One indexing is only the default, and Fortran has long supported the declaration of any initial boundary that the programmer wants. So, it was a step backward that c_f_pointer made you use one indexing. But with Fortran 2003 there is a fix: overriding pointers:
arr (0:n-1) => arr
instead of 1: n or whatever.
Then pass the array to the subroutine and it will get the assigned boundaries.
EDIT: Improve the demo showing the difference between allocatables and pointers. The pointer passes the boundaries of the array. A regular array passes the form ... you can declare the first dimension in the routine, if you want, and let the shape control be the second.
module mysubs implicit none contains subroutine testsub ( ptr, alloc, start, array ) real, pointer, dimension (:) :: ptr real, dimension (:), intent (in) :: alloc integer, intent (in) :: start real, dimension (start:), intent (in) :: array write (*, *) "pointer in sub:", lbound (ptr, 1), ubound (ptr, 1) write (*, *) ptr write (*, *) "1st array in sub:", lbound (alloc, 1), ubound (alloc, 1) write (*, *) alloc write (*, *) "2nd array in sub:", lbound (array, 1), ubound (array, 1) write (*, *) array return end subroutine testsub end module mysubs program test_ptr_assignment use mysubs implicit none real, pointer, dimension(:) :: test real, allocatable, dimension(:) :: alloc1, alloc2 real, allocatable, dimension(:) :: alloc1B, alloc2B allocate ( test (1:5), alloc1 (1:5), alloc1B (1:5) ) test = [ 1.0, 2.0, 3.0, 4.0, 5.0 ] alloc1 = test alloc1B = test write (*, *) "A:", lbound (test, 1), ubound (test, 1) write (*, *) test call testsub (test, alloc1, 1, alloc1B ) test (0:4) => test allocate ( alloc2 (0:4), alloc2B (0:4) ) alloc2 = test alloc2B = test write (*, *) write (*, *) "B:", lbound (test, 1), ubound (test, 1) write (*, *) test call testsub (test, alloc2, 0, alloc2B) stop end program test_ptr_assignment