- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the following, I have an interface file, say interface.fi as below,
module foo_type type bar end type bar end module foo_type module foo use foo_type interface subroutine sub(var) use foo_type type(bar) var end subroutine sub end interface end module foo
And there are multiple source files use the models in this file, say pr.f90
include "interface.fi" program prg use foo type(bar) b call sub(b) end program prg
and another sub.f90
include "interface.fi" subroutine sub(var) use foo type(bar) var end subroutine sub
Now consider I compile them as below,
ifort -c sub.f90 ifort -c prg.f90 ifort -o prg sub.o prg.o
And I get the error
duplicate symbol _foo_type._ in: sub.o prg.o duplicate symbol _foo._ in: sub.o prg.o
It appears that both translation unit generates symbols for the module foo_type and foo. If I only include the interface file in only one source file. And in the Makefile make sure that it is compiled first, or just compile it first to generate models and do not include it in only source files. Then everything works fine. This is ok for small project where write a Makefile manually is not too much a trouble. But in other build systems, say, CMake for a larger program, I often has to write a custom command just to make sure that certain module files are generated first.
In addition, it appears that using gfortran there is no such problem. Is there a solution that I can just include the interface file wherever its members are used and still compile successfully, without going into the trouble to make sure there is only one instance of the modules being included?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The F95 and F2003 languages do not allow an interface-to-self, but that is what you are providing when you write "use foo" in in sub.f90.
There is also a bit of self-deception resulting from naming the first file "interface.fi", when the file contains not only the interface but also a definition of the type "bar". The "include" directive in pr.f90, etc., creates multiple instances of module "foo" to appear in the object files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
NB: "Interface to self" has been debated among the standards committee, but was ultimately rejected. As mecej4 says, it's not allowed by the standard. gfortran may choose to support it as an extension. The multiple definitions of the module are simply an error in your program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your program will compile and run of you delete the 'include "interface.fi"' and the use to self
The "use foo" is sufficient in the external source files (assuming path to foo.mod is in your project include path).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
use foo in subroutine sub need not be nonconforming. In fact, there is an idiom available for subroutine sub to generate code to check the interface specification given for itself while requesting the optimizer to not generate any code for it:
include "interface.fi" subroutine sub(var) use foo use foo, only: self=>sub type(bar) var if(.FALSE.) then BLOCK procedure(self), pointer :: p p=>sub END BLOCK end if end subroutine sub
Unfortunately, ifort generates a spurious error for the above, even when sub is declared recursive:
sub.f90(10): error #8191: The procedure target must be a procedure or a procedur e pointer. p=>sub -------------^
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RO and woodbird, et all
The use of: include "interface.fi"
in multiple source files, where the contents of interface.fi declares the module is in error as this can lead to multiple declarations of the module, with potentially different definitions (e.g. two different versions of your interface.fi in different paths).
You can USE the .mod file multiple times, but you cannot (ought not) multiply define a module (even if identical). In this way Fortran differs from C++'s #include (with member functions, and inline code).
I generally place my interfaces, alone in a separate file that generates a .mod file. This is kept separate from the code, as you might in a module with data + code in a contains section. The reason being, on large solutions this cuts down on the build times. interfaces seldom change, while data and/or code change more frequently. No need to recompile a source file when the interface does not change, but the called routine code has changed.
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page