|
From: James Van Buskirk on 6 Apr 2008 20:15 "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
First
|
Prev
|
Pages: 1 2 Prev: The structure contains one or more misaligned fields Next: Using Modules |