Вопрос

I've inherited a legacy Fortran 77 code that I now try to get to compile in the Fortran 2003 standard. I have no clue about Fortran (I know C and Python), I'm picking it up on the way.

The below code snippet causes a compiler error (also given below). To be honest, just to look at this code gives me a head-ache: I really don't understand how one could write a line of code such as

A(i) = A(i) + B(q)

where both A and B are functions. I am familiar with the concept of recursive functions in C and Python, and if I were the compiler in this situation that is presented here, I would probably complain and raise at least a WTF warning.

I don't expect anyone to fix this code for me. I'd be more than happy if someone could explain to me what is (tried) to be achieved by the line:

cipr(IPR_WADV, ipa_idx, ispc) = cipr(IPR_WADV, ipa_idx, ispc) + fc1(l)/dy/depth(i,j,k)  

or refer me to a good place where I can look that up.

Below are the code snippet and the corresponding compiler error.

IF( lipr ) THEN
    !-----Change from X-direction horizontal advection
    l = 1
    DO i=i1+1,i2-1
        l = l+1
       IF( ipa_cel(i,j,k) .GT. 0 ) THEN
          ipa_idx = ipa_cel(i,j,k)
          !-----Flux at west boundary
          cipr(IPR_WADV, ipa_idx, ispc) = cipr(IPR_WADV, ipa_idx, ispc) + fc1(l)/dy/depth(i,j,k)          
          !-----Flux at east boundary
          cipr(IPR_EADV, ipa_idx, ispc) = cipr(IPR_EADV, ipa_idx, ispc) + fc2(l)/dy/depth(i,j,k)
          !-----Average volume
          cipr(IPR_VOL, ipa_idx, ispc) = cipr(IPR_VOL, ipa_idx, ispc) + dx(j)*dy*depth(i,j,k)
          npastep(ipa_idx,ispc) = npastep(ipa_idx,ispc) + 1
          END IF
    END DO
END IF

the compiler gives this output message as an error

gfortran -std=f2003  -c -g -o build/Debug/GNU-Linux-x86/xyadvec.o
xyadvec.f03 xyadvec.f03:177.42:

cipr(IPR_WADV, ipa_idx, ispc) = cipr(IPR_WADV, ipa_idx, ispc) + fc1(l
                               1 
Error: Statement function at (1) is recursive
Это было полезно?

Решение

Probably cipr is an array, and somehow the compiler doesn't know that. In that case, the line is interpreted as being a statement function.

For example,

program dummy
dimension c(10)
c(i) = c(i) + d
end program

this will compile (besides warnings about unitialized variable usage), as c is an array and the line updates an element in the array, similar to what c[i] += d would do in C.

If c is not an array, then the line will be interpreted as a one-line function, similar to a macro. So, e.g.:

program dummy
c(i) = 2*i
...
myvar = c(2)
end program

here c is a function that returns twice the argument, so myvar would be 4.

So, in your case, I would guess from the usage that cipr is intended to be an array and there is something wrong with declaration of cipr or with some include files that declare the dimension of cipr. Because the compiler then interprets it as a statement function, it fails.

Can you give the entire file where this line occurs?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top