将模块变量设为私有

时间:2019-03-26 00:38:18

标签: module fortran

在过去的几年中,我一直在创建带有子例程的多个模块,然后将它们用于不同的项目。当我在那些特定于项目的文件之一中定义与这些模块中定义的变量名冲突的参数变量时,我遇到了问题。是否可以将这些名称设置为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设为私有?

我知道一个选项可能是在模块中使用“非通用”变量名,或者使用禁止名称列表,但是这似乎很复杂(需要编辑太多文件,并且与书籍/概述了这些程序的论文),这将使与同事的协作更加困难。

1 个答案:

答案 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

要避免的方式:

  1. 将一个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
    
  2. 仅导入所需的零件:

    program progtest
        use modA, only: subA
        use modB
        implicit none
    ...
    
  3. 重命名x中的一个或两个:

    use modA
    use modB, only: xB => x
    ...
    call subA(xB(1))