Reputation: 69
I tried the following code to get the code to work correctly. It seems I need to write an interface to avoid mistaken results. I wrote the following, but it does not pass the compiling stage. The errors are the following: (use gfortran compiler)
fit.f90:34.16:
TYPE(spec), INTENT(IN) :: SMP
1
Error: Derived type 'spec' at (1) is being used before it is defined
fit.f90:35.12:
REAL(q), INTENT(OUT) :: RES
1
Error: Symbol 'q' at 1 has no IMPLICIT type
...
Here is the compilable code to illustrate the issue.
MODULE prec
INTEGER, PARAMETER :: q=8
END MODULE prec
MODULE MOD_FIT
USE prec
INTEGER, PARAMETER :: NO_NI=200
TYPE spec
! source of fitting
INTEGER NW
COMPLEX(q), POINTER :: W(:),G(:)
! how spectrum is parametrized
INTEGER NO_NM ! continuous points labeled as 1,2,3,...,NO_NM
REAL(q), ALLOCATABLE :: O_N(:),O_D(:) ! frequency
REAL(q), POINTER :: A_N(:),B_N(:),A_D(:) ! A(Omega)
END TYPE
TYPE(spec) SMP
INTERFACE
SUBROUTINE NNLS_CMPLX(SMP,RES,RES_V)
IMPLICIT NONE
TYPE(spec), INTENT(IN) :: SMP
REAL(q), INTENT(OUT) :: RES
COMPLEX(q), OPTIONAL, INTENT(OUT) :: RES_V(SMP%HN)
END SUBROUTINE NNLS_CMPLX
END INTERFACE
CONTAINS
SUBROUTINE NNLS_CMPLX(SMP,RES,RES_V)
IMPLICIT NONE
TYPE(spec) :: SMP
REAL(q) :: RES
COMPLEX(q), OPTIONAL :: RES_V(*)
RES=0
IF(PRESENT(RES_V)) RES_V(1)=0
END SUBROUTINE NNLS_CMPLX
END MODULE MOD_FIT
PROGRAM MAIN
USE prec; USE MOD_FIT
REAL(q) PK_RES
COMPLEX(q) RES_V(4)
CALL NNLS_CMPLX(SMP,PK_RES,RES_V)
END
Upvotes: 0
Views: 910
Reputation: 60058
Having an explicit interface means that the compiler knows how the called subroutine or function (procedure) looks like.
Explicit interfaces should not be normally provided by an interface block, that is the thing:
interface
...
end interface
but by placing the procedures in modules instead.
You definitely cannot use an interface block for a module procedure (a procedure placed inside a module). Interface block tells that there is some external procedure somewhere with the properties you declare in the interface block. But your procedure is not external, it is in a module.
Just remove the interface block and it should work.
Just a suggestion: use small caps and indentation in your code. It is very difficult to read as it stands.
To explain the actual error message: As francescalus comments, interface blocks have a separate scope. If they are placed in a module, they do not see the other contents of the module. That's why the compiler complains it does not know what spec
and q
are.
Upvotes: 1