fortran77 code execution does not stop
Question
There is a F77 code, slightly modified from me. The code calls a particular routine, but it seems that compilation does not stop (and I believe there is no problem with loops). This makes me wonder why this might happen.
Second i cannot really understand what the output of that routine will be. Can anyone help here?
this is the section of the code that calls the routine/function. By working a MWE,
integer, parameter:: nf=101, ns=7, nas=427, na=61, nxm=3
integer:: i,j,k,
allocate(xf(nf), xa(na))
allocate(absa(nxm,na-1), wgta(nxm,na-1),absf(nxm,nf-1), wgtf(nxm,nf-1))
do 150 i=1,na-1
call qgausl (nxp(i), xa(i), xa(i+1), absa(1,i), wgta(1,i))
150 continue
do 160 i=1,nf-1
call qgausl (nxp(i), xf(i), xf(i+1), absf(1,i), wgtf(1,i))
160 continue
And this is the routine
subroutine qgausl(n,x1,x2,x,w)
implicit none
integer:: n, m
real*8:: xl,x2, x1, xm, eps, z, p1,p2,p3, pp, z1
real*8:: x(n), w(n)
eps=1.0e-8
m=(n+1)/2
xm=0.5*(x2+x1)
xl=0.5*(x2-x1)
do 12 i=1,m
z = cos(3.141592654*(i-.25)/(n+.5))
1 continue
print*, z
p1 = 1.0
p2 = 0.0
do 11 j=1,n
p3 = p2
p2 = p1
p1 = ((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j
11 continue
pp = n*(z*p1-p2)/(z*z-1.0)
z1 = z
z = z1-p1/pp
if (dabs(z-z1).gt.eps) go to 1
x(i) = xm-xl*z
x(n+1-i) = xm+xl*z
w(i) = 2.0*xl/((1.0-z*z)*pp*pp)
w(n+1-i) = w(i)
12 continue
return
end subroutine
For your information and if I made a good job, i translated this into Matlab and seems that there is no problem with the loops in the routine.
Solution
A bit of an extended comment:
One thing I notice is you tagged this as fortran77 but in fact it will not compile if this is indeed an f77-type external subroutine (ie. not in a module/contains construct) because you use implicit none
but fail to declare i
in the subroutine.
( There are numerous other post-f77 syntax features in there as well. )
So...assuming this subroutine is internal (ie. lives within contains in the calling routine) the i
here :
do 12 i=1,m
is the same i
from the scope of the calling routine, ie. you are effectively using the same variable for two nested loops.
This is obviously an illegal thing to do, and I must say I'm disturbed to see that gfortran silently compiles such and runs off in an endless loop.. (!?!)
I'd suggest moving the subroutine to a module or simply making it external if you think this is the case. Then the compiler will flag your failure to declare i
example
both gfortran and ifort compile this without warnings:
implicit none
integer j
do j = 1,2
call x()
enddo
contains
subroutine x()
implicit none
do j=3,4
write(*,*)j
enddo
end subroutine
end
the gfortran version runs away endlessly printing 3,4,3,4. The intel version writes 3,4 just once (ie not what you might expect either)
declaring j
in the subroutine fixes it of course..