I have an interface block to define a generic subroutine which have an assumed size array as dummy argument (in order to be able to act on 'the middle' of a passed array, like a C pointer) and it does not compile. Here is simple exemple:
module foo
interface sub
module procedure isub
module procedure dsub
end interface
contains
subroutine isub(a,n)
integer, intent(in) :: a(*), n
integer :: i
print*, 'isub'
do i=1,n
print*, a(i)
enddo
end subroutine isub
subroutine dsub(a)
real(8), intent(in) :: a(*)
integer, intent(in) :: n
integer :: i
print*, 'dsub'
do i=1,n
print*, a(i)
enddo
end subroutine dsub
end module foo
program test
use foo
implicit none
integer :: ai(4)
real(8) :: ad(4)
ai=(/1,2,3,4/)
ad=(/1.,2.,3.,4./)
call sub(ai,3)
call sub(ad,3)
call isub(ai(2),3)
!call sub(ai(2),3)
end program test
The commented line does not compile, whereas it is ok when calling directly the subroutine with call isub(ai(2),3)
(tested with gfortran and ifort). Why and is it possible to have it to work with call sub(ai(2),3)
?
edit: with ifort, it says:
$ ifort overload.f90
overload.f90(37): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
call sub(ai(2),3)
-------^
compilation aborted for overload.f90 (code 1)
Thanks
You are passing a scalar to a function that is expecting an array. Try
call sub(ai(2:2))
which is passing an array of length one. I'm wondering why call isub(ai(2))
is accepted, though...
To answer your new question (partly in the comments):
If you restrict yourself to contiguous arrays, you can use call sub(ai(2:4))
without loss of performance using deferred shape arrays:
subroutine isub(a)
integer,intent(in) :: a(:)
integer :: i
print*, 'isub'
do i=1,size(a)
print*, a(i)
enddo
end subroutine isub
There are no temporary arrays created with ifort
or gfortran
. You can check for this using:
ifort -check arg_temp_created
gfortran -Warray-temporaries