如何将模块变量指定为接口块内的伪参数声明的一部分?
How do you specify a module variable as a part of dummy argument declaration inside an interface block?
我有一个子程序 sub_x
定义为
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
.
.
也就是说,sub_x
依赖模块变量 m
作为其数组参数的范围。现在,在一个单独的文件中,sub_x
的界面块如下
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
并且任何调用 sub_x
的过程都会有一个 use mod_x
语句。当尝试编译包含模块 mod_x
、file_x.f90
和 ifort -c file_x.f90
的文件时,我收到错误消息“IMPORT-name 必须是主机作用域单元中实体的名称。[m]”显示编译器无法解析 m
。由于 mod_x
定义中存在 use, intrinsic :: iso_c_binding
,它可能能够解析 c_long
和 c_double
,但我可能错了。在 mod_x
定义中添加 use mod_a, only : m
可能会解决问题,但这意味着 mod_x
将依赖于 mod_a
并且我尽量避免模块之间的依赖性。
一种似乎有效的方法是将接口块移动到一个纯文本文件,比如 interface_x.f90
,并在任何调用 sub_x
的过程中添加一个 include "interface_x.f90"
行。但我尽量避免使用这种方法,因为我有数十个外部子程序,最好将所有这些子程序的接口放在一个文件中。如果我要使用它,几乎所有具有 include "interface_x.f90"
的过程都必须具有 use mod_a, only : m
,即使它不需要 m
。有什么解决办法?
没有必要使用 import
语句使实体在界面块中可访问。这是一种方式,在某些情况下是唯一的方式。这不是其中之一。
import
语句控制范围块(例如接口块)的主机范围内实体的可访问性。在问题的(简化)情况下
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x()
import :: c_long
end
end interface
end module mod_x
import 语句使模块范围内的实体 c_long
在 sub_x
的接口规范中可访问。该实体本身在模块范围内可用,因为它与模块 iso_c_binding
.
关联
在接口规范中可以访问完全相同的实体
module mod_x
interface
subroutine sub_x()
use, intrinsic :: iso_c_binding, only : c_long
end
end interface
end module mod_x
这与 sub_x
的实际子例程规范非常相似。 m
可以用同样的方式访问:
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
(或者等效地通过在模块范围内组合 import
和 use mod_a
。)
请注意,无论您以何种方式编写,这都是一个模块依赖关系:mod_x
依赖于 mod_a
,因为 mod_x
中指定的接口具有由 [=] 中的实体确定的特征23=].
我有一个子程序 sub_x
定义为
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
.
.
也就是说,sub_x
依赖模块变量 m
作为其数组参数的范围。现在,在一个单独的文件中,sub_x
的界面块如下
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
并且任何调用 sub_x
的过程都会有一个 use mod_x
语句。当尝试编译包含模块 mod_x
、file_x.f90
和 ifort -c file_x.f90
的文件时,我收到错误消息“IMPORT-name 必须是主机作用域单元中实体的名称。[m]”显示编译器无法解析 m
。由于 mod_x
定义中存在 use, intrinsic :: iso_c_binding
,它可能能够解析 c_long
和 c_double
,但我可能错了。在 mod_x
定义中添加 use mod_a, only : m
可能会解决问题,但这意味着 mod_x
将依赖于 mod_a
并且我尽量避免模块之间的依赖性。
一种似乎有效的方法是将接口块移动到一个纯文本文件,比如 interface_x.f90
,并在任何调用 sub_x
的过程中添加一个 include "interface_x.f90"
行。但我尽量避免使用这种方法,因为我有数十个外部子程序,最好将所有这些子程序的接口放在一个文件中。如果我要使用它,几乎所有具有 include "interface_x.f90"
的过程都必须具有 use mod_a, only : m
,即使它不需要 m
。有什么解决办法?
没有必要使用 import
语句使实体在界面块中可访问。这是一种方式,在某些情况下是唯一的方式。这不是其中之一。
import
语句控制范围块(例如接口块)的主机范围内实体的可访问性。在问题的(简化)情况下
module mod_x
use, intrinsic :: iso_c_binding
interface
subroutine sub_x()
import :: c_long
end
end interface
end module mod_x
import 语句使模块范围内的实体 c_long
在 sub_x
的接口规范中可访问。该实体本身在模块范围内可用,因为它与模块 iso_c_binding
.
module mod_x
interface
subroutine sub_x()
use, intrinsic :: iso_c_binding, only : c_long
end
end interface
end module mod_x
这与 sub_x
的实际子例程规范非常相似。 m
可以用同样的方式访问:
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
(或者等效地通过在模块范围内组合 import
和 use mod_a
。)
请注意,无论您以何种方式编写,这都是一个模块依赖关系:mod_x
依赖于 mod_a
,因为 mod_x
中指定的接口具有由 [=] 中的实体确定的特征23=].