It is possible to check whether an optional argument has the right dimensions without using a nested loop, as shown in subroutine twice
.
module m_mod
implicit none
contains
function first_false(tf) result(ipos)
logical, intent(in) :: tf(:)
integer :: ipos
ipos = findloc(tf,.false.,dim=1)
end function first_false
!
subroutine twice(i,j,ierr)
integer, intent(in) :: i(:,:)
integer, intent(out), optional :: j(:,:)
integer, intent(out) :: ierr
ierr = 0
if (present(j)) ierr = first_false(shape(i)==shape(j)) ! test that optional argument j conforms with i
if (ierr == 0 .and. present(j)) j = 2*i
end subroutine twice
subroutine thrice(i,j,ierr) ! more verbose
integer, intent(in) :: i(:,:)
integer, intent(out), optional :: j(:,:)
integer, intent(out) :: ierr
ierr = 0
if (present(j)) then
if (size(i,1) /= size(j,1)) then
ierr = 1
else if (size(i,2) /= size(j,2)) then
ierr = 2
end if
if (ierr /= 0) return
j = 3*i
end if
end subroutine thrice
end module m_mod
!
program main
use m_mod, only: twice
implicit none
integer :: i(2,3),j(2,2),k(2,3),ierr
i = 5
call twice(i,j,ierr)
print*,"ierr=",ierr
call twice(i,ierr=ierr)
print*,"ierr=",ierr
call twice(i,k,ierr)
print*,"ierr=",ierr
print*,"k=",k
end program main
Running this gives
ierr= 2
ierr= 0
ierr= 0
k= 10 10 10 10 10 10