4

In a Fortran 2003 module I'm defining a type called t_savepoint and, later, I want to define an interface for a subroutine called fs_initializesavepoint, which takes an object of type t_savepoint as only argument.

Here is the code for the whole module:

module m_serialization

    implicit none

    type :: t_savepoint
        integer :: savepoint_index
        real    :: savepoint_value
    end type t_savepoint

    interface

        subroutine fs_initializesavepoint(savepoint)
            type(t_savepoint) :: savepoint
        end subroutine fs_initializesavepoint


    end interface

end module m_serialization

The reason why I want such an interface is that later on I will make this fortran module interoperate with C.

If I try to compile it (gfortran-4.7.0), I get the following error message:

            type(t_savepoint) :: savepoint
                                          1
Error: The type of 'savepoint' at (1) has not been declared within the interface

The error disappears if I move the definition of the type inside the subroutine; but if then I want to use the same type within many subroutines, should I repeat the definition in all of them?

Thank you in advance.

EDIT: a solution would be to move the definition of the type onto another module and then to use it in every subroutine. However I don't like this solution too much, because the type t_savepoint and the subroutines are part of the same conceptual topic.

1
  • 2
    As an aside, unless the type has BIND(C) or is a SEQUENCE type then if you "repeat the definition" of a type you actually declare a completely new type (even though it has the same name and same components, etc). This would result in (confusing) errors when the compiler checks the type of the actual arguments against the dummy declarations. Hence for non-BIND(C), non-SEQUENCE types you must either use your "other module" solution (F95) or the F2003 import statement described by Ian Bush. Commented Dec 13, 2012 at 11:48

1 Answer 1

9

Rightly or wrongly in an interface block you don't have access to the environment by host association. To fix this you need to import the datatype exlicitly:

[luser@cromer stackoverflow]$ cat type.f90
module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

  interface

     subroutine fs_initializesavepoint(savepoint)
       Import :: t_savepoint
       type(t_savepoint) :: savepoint
     end subroutine fs_initializesavepoint


  end interface

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

This is f2003.

However I suspect the way you have put this suggests you are not going about coding this up the best way. Better is simply to put the routine itself in the module. Then you don't need bother with the interface at all:

module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

Contains

  Subroutine fs_initializesavepoint(savepoint)

    type(t_savepoint) :: savepoint 

    Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value

  End Subroutine fs_initializesavepoint

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

Given that modules are really designed to deal with connected entities this is really the way to do it in Fortran. It also has the advantage of only requiring a f95 compiler, so is universally available (though admittedly import is commonly implemented)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, Ian! The import statement solved my issue. Also thanks for your further comments. Anyway, le me explain that I need exactly the first version, because I won't implement the subroutine in Fortran, but in C. Therefore, I just need an interface to be available for syntax-checking. I'm also using the C interoperability features, so I need F2003 anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.