bsmile
bsmile

Reputation: 69

what is the correct way to write a specific interface in fortran?

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

Answers (1)

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

Related Questions