在过去的几年中,我一直在创建带有子例程的多个模块,然后将它们用于不同的项目。当我在那些特定于项目的文件之一中定义与这些模块中定义的变量名冲突的参数变量时,我遇到了问题。是否可以将这些名称设置为subroutine-private或module-private?
这里是一个例子。假设我有以下模块:
module mymod
implicit none
contains
subroutine test1(x)
real, intent(in) :: x(:)
print *, x**2.0
end subroutine test1
end module mymod
然后该模块由主程序调用
program main
use mymod
implicit none
real :: y
real,dimension(2,1),parameter :: x = [1.0,2.0]
y = 3.0
call test1(y)
end program main
在这种情况下,假设主程序中的x
被定义为与子程序x
中的test1
不同尺寸的参数,则编译时会出现问题(形状匹配违反规则)。有什么方法可以将模块x
中的mymod
设为私有?
我知道一个选项可能是在模块中使用“非通用”变量名,或者使用禁止名称列表,但是这似乎很复杂(需要编辑太多文件,并且与书籍/概述了这些程序的论文),这将使与同事的协作更加困难。
答案 0 :(得分:-1)
其中两个不同的问题:
示例程序为何无法编译:
这与公共或私有无关,或者在程序本身中定义了x
。
这与以下事实有关:在模块中,x
作为参数定义为一维数组,而在主程序中,y
是标量。
尝试一下,在主程序中删除x
的声明,它仍然会失败。
(实际上,无论如何,声明都不能这样工作,您可以将x
声明为2维数组(形状2、1),然后将其赋予1维数组。必须做类似的事情:
real, dimension(2, 1), parameter x = reshape([1.0, 2.0], [2, 1])
但是要摆脱您描述的错误,您需要通过删除(:)
后面的real, intent(in) :: x
来更改子例程接口,或将调用更改为call test1([y])
。
两个模块导入相同名称的不同变量时,该怎么办:
如果您说有这个,那就不一样了
module modA
implicit none
real, parameter :: x = 2.0
contains
subroutine subA(k)
real, intent(in) :: k
print *, k*x
end subroutine subA
end module modA
module modB
implicit none
real :: x(3)
end module modB
program progtest
use modA
use modB
implicit none
call subA(x(1))
end program progtest
在此示例中,它将尝试从两个模块中导入变量x
。
要避免的方式:
将一个x
设为私有:
implicit none
real, parameter, private :: x = 2.0
或
real, parameter :: x = 2.0
private :: x
或
implicit none
private
real, parameter :: x = 2.0
public :: subA
仅导入所需的零件:
program progtest
use modA, only: subA
use modB
implicit none
...
重命名x
中的一个或两个:
use modA
use modB, only: xB => x
...
call subA(xB(1))