I have a subroutine sub_x
defined as
subroutine sub_x(n, a)
use, intrinsic :: iso_c_binding
use mod_a, only : m
implicit none
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
.
.
.
rest of the codes
.
.
That is, sub_x
depends on a module variable m
as an extent of its array argument. Now, in a separate file, the interface block of sub_x
goes as follows
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x(n, a)
import :: c_long, c_double, m
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
end
end interface
end module mod_x
And any procedure calling sub_x
will have a use mod_x
statement. When trying to compile the file containing module mod_x
, file_x.f90
with ifort -c file_x.f90
I got error saying "IMPORT-name must be the name of an entity in the host scoping unit. [m]" showing that the compiler was not able to resolve m
. It may be able to resolve c_long
and c_double
because of the presence of use, intrinsic :: iso_c_binding
in mod_x
definition, but I may be wrong. Adding use mod_a, only : m
in mod_x
definition may solve the issue, but that means mod_x
will depend on mod_a
and I try to avoid dependency between modules.
One way that seems to work is to move the interface block to a plain text file, say interface_x.f90
, and add an include "interface_x.f90"
line in any procedure calling sub_x
. But I try to avoid using this method because I have tens of external subroutines and it's better to have the interfaces of all of them in a single file. If I were to use this, just about any procedure having an include "interface_x.f90"
will have to have use mod_a, only : m
even though it doesn't need m
. What's the solution?
It is not necessary to use an import
statement to make an entity accessible in an interface block. It is one way, and in some cases the only way. This is not one of those cases.
The import
statement controls accessibility of entities from the host scope of a scoping block (such as an interface block). In the (simplified) case of the question
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x()
import :: c_long
end
end interface
end module mod_x
the import statement makes the entity c_long
from the module scope accessible in the interface specification of sub_x
. That entity is itself available in the module scope because it is use associated from the module iso_c_binding
.
Exactly the same entity is made accessible in the interface specification by
module mod_x
interface
subroutine sub_x()
use, intrinsic :: iso_c_binding, only : c_long
end
end interface
end module mod_x
This is much as in the actual subroutine specification of sub_x
. m
can be made accessible in the same way:
module mod_x
interface
subroutine sub_x(n, a)
use, intrinsic :: iso_c_binding, only : c_long, c_double
use mod_a, only : m
integer(c_long), intent(in) :: n
real(c_double), intent(in) :: a(1:m)
end
end interface
end module mod_x
(Or equivalently by combining an import
with use mod_a
in the module scope.)
Note that this is a module dependency whichever way you write it: mod_x
depends on mod_a
because the interface specified in mod_x
has a characteristic determined by an entity in mod_a
.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments