Gfortran немного параноик с интерфейсами. Он хочет знать не только тип, вид, ранг и количество аргументов, но также форму, целевой атрибут и намерение (хотя я согласен с частью намерения). Я столкнулся с подобной проблемой.
В gfortran существует три разных определения размеров:
1. Исправлено
2. Переменная
3. Предполагаемый размер
При использовании ifort категории 1 и 2 считаются одинаковыми, поэтому вы можете просто определить любой размер измерения как 0 в интерфейсе, и он работает.
program test
implicit none
integer, dimension(:), allocatable :: ownlist
interface
subroutine blueprint(sz,arr)
integer, intent(in) :: sz
integer, dimension(0), intent(in) :: arr
! This zero means that the size does not matter,
! as long as it is a one-dimensional integer array.
end subroutine blueprint
end interface
procedure(blueprint), pointer :: ptr
allocate(ownlist(3))
ownlist = (/3,4,5/)
ptr => rout1
call ptr(3,ownlist)
deallocate(ownlist)
allocate(ownlist(0:10))
ownlist = (/3,4,5,6,7,8,9,0,1,2,3/)
ptr => rout2
call ptr(3,ownlist)
deallocate(ownlist)
contains
! This one has a dimension size as input.
subroutine rout1(sz,arr)
implicit none
integer, intent(in) :: sz
integer, dimension(sz), intent(in) :: arr
write(*,*) arr
write(*,*) arr(1)
end subroutine rout1
! This one has a fixed dimension size.
subroutine rout2(sz,arr)
implicit none
integer, intent(in) :: sz
integer, dimension(0:10), intent(in) :: arr
write(*,*) "Ignored integer: ",sz
write(*,*) arr
write(*,*) arr(1)
end subroutine rout2
end program test
Gfortran жалуется на интерфейс. Изменение 0 в 'sz' решает проблему четыре 'rout1', но не для 'rout2'.
Однако вы можете обмануть gfortran и сказать, что размерность (0: 10 + 0 * sz) вместо размерности (0:10) и gfortran компилирует и дает то же самое
результат как ifort.
Это глупый трюк, и он основан на существовании целого числа 'sz', которого может и не быть. Другая программа:
program difficult_test
implicit none
integer, dimension(:), allocatable :: ownlist
interface
subroutine blueprint(arr)
integer, dimension(0), intent(in) :: arr
end subroutine blueprint
end interface
procedure(blueprint), pointer :: ptr
allocate(ownlist(3))
ownlist = (/3,4,5/)
ptr => rout1
call ptr(ownlist)
deallocate(ownlist)
allocate(ownlist(0:10))
ownlist = (/3,4,5,6,7,8,9,0,1,2,3/)
ptr => rout2
call ptr(ownlist)
deallocate(ownlist)
contains
subroutine rout1(arr)
implicit none
integer, dimension(3), intent(in) :: arr
write(*,*) arr
write(*,*) arr(1)
end subroutine rout1
subroutine rout2(arr)
implicit none
integer, dimension(0:10), intent(in) :: arr
write(*,*) arr
write(*,*) arr(1)
end subroutine rout2
end program difficult_test
Это работает под ifort по тем же причинам, что и в предыдущем примере, но gfortran жалуется на интерфейс. Я не знаю, как я могу это исправить.
Единственное, что я хочу сказать гфортрану: «Я еще не знаю размерный размер, но мы исправим его». Но для этого нужно лишнее целое число (или что-то еще, что мы можем превратить в целое число), чтобы обмануть gfortran.