Да, это была проблема из-за ограничения c_f_pointer.Как вы обнаружили, встроенный c_f_pointer поддерживает только границы, начинающиеся с индекса 1. Люди часто утверждают, что Fortran - это язык с одним индексом, но это не так.Одна индексация используется только по умолчанию, и Fortran давно поддерживает объявление любой начальной границы, которую хочет программист.Так что это был шаг назад, когда c_f_pointer заставил вас использовать одну индексацию.Но в Fortran 2003 есть исправление: переопределение границ указателя:
arr (0:n-1) => arr
вместо 1: n или что угодно.
Затем передайте массив подпрограмме, и он получитпредполагаемые границы.
РЕДАКТИРОВАТЬ: улучшить демонстрационную программу, показывая разницу между назначаемыми и указателями.Указатель переходит границы массива.Обычный массив передает форму ... вы можете объявить первое измерение в подпрограмме, если хотите, и позволить форме управлять вторым.
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