From: James Van Buskirk on
"Tobias Burnus" <burnus(a)net-b.de> wrote in message
news:448ebf53-39c6-4737-8106-8c3fad1290e0(a)s50g2000hsb.googlegroups.com...

> I believe the program is invalid. Quoting the Fortran 2003 standard:

> "12.4.1.3 Actual arguments associated with dummy procedure entities"
> [...]
> "If the interface of the dummy argument is implicit and either the
> name of the
> dummy argument is explicitly typed or it is referenced as a function,
> the dummy
> argument shall not be referenced as a subroutine"

> As you once reference "qsub" as function and once as subroutine (by
> using them as actual argument), the program is invalid and the
> compiler is free to reject it. Interestingly, most compiler accept a
> reduced version which contains such calls. For the most reduced
> version which uses implicit typing, of my compilers, only gfortran
> rejects it. For the full program, most of my compilers reject it.

> In conclusion, I think gfortran is right and your program is invalid.

OK, I like that passage. However, if we go back to the start of
section 12.4 we see:

"The forms of procedure reference are:"

"R1217 function-reference is procedure-designator([actual-arg-spec-list])"

"R1218 call-stmt is CALL procedure-designator[([actual-arg-spec-lest])]"

So using a procedure as an actual argument does not seem to count as
a reference of the actual argument procedure. The really tough case
lies in subroutine C, and here the program really is nonconforming,
but the compilers were rejecting the program for other reasons.

subroutine C(sub, n)
integer, intent(in) :: n
interface
function sub(n)
implicit none
integer, intent(in) :: n
integer sub
end function sub
end interface

if(n /= 2) then
write(*,*) 'In subroutine C, result of subC = ', sub(n)
else
write(*,*) 'Nothing to do in subroutine C'
end if
end subroutine C

Subroutine C, as seen above, has a function dummy argument but is
ultimately passed a subroutine actual argument. Now if we changed
it around a bit so that the specification part were:

implicit integer s
integer, intent(in) :: n
external sub

the question gets more interesting: does linguistic reference
count as reference or does the thread of execution actually have
to include the procedure reference for it to count as a reference?
Although it may seem obvious that linguistic reference is sufficient,
there are other instances, for example where a pointer with undefined
association status is passed as an actual argument but is still OK
provided the association status of the pointer is never checked nor
relied on in the callee.

Even if subroutine C cannot be passed a subroutine as an actual
argument, we could comment out one of the lines that leads to
invoking it in this fashion and both gfortran and ifort would
still reject it. I think that the standard might permit passing
anonymous procedures around like this. Certainly it could be
done via C_FUNPTRs. Let me know what you think.

P.S. earlier I remarked that f95 doesn't have a way to make all
possible interfaces explicit if a recursive procedure is passed
itself as an actual argument. I recall that I had been informed
a long time ago that it is possible to do this in f03, so another
example:

C:\gfortran\clf\ambinterf>type recurse.f90
module recursive_mod
implicit none
contains
recursive subroutine sub(x, depth)
procedure(sub) x
integer, intent(in) :: depth

if(depth > 0) then
write(*,*) 'In sub, depth = ', depth
call x(sub, depth-1)
end if
end subroutine sub
end module recursive_mod

program test
use recursive_mod
implicit none

call sub(sub, 10)
end program test

C:\gfortran\clf\ambinterf>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran
recurse
..f90 -orecurse

C:\gfortran\clf\ambinterf>recurse
In sub, depth = 10
In sub, depth = 9
In sub, depth = 8
In sub, depth = 7
In sub, depth = 6
In sub, depth = 5
In sub, depth = 4
In sub, depth = 3
In sub, depth = 2
In sub, depth = 1

Sorry, couldn't resist!

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end