如何在公共块和模块之间共享数据?

时间:2016-09-15 21:53:39

标签: fortran intel-fortran

如何使用旧代码将新Fortran 90模块与尽可能少的修改进行接口?我们的想法是在子程序中为新代码使用“模块”,同时尽可能少地修改旧代码(即保持公共块不受影响)。

为了演示我打算实现的目标,这里有一个简单的程序:

考虑一个简单的程序:

  module Bmod
     real*8 x
  end module Bmod

  program main
    use Bmod
    common /a/ x   ! old code                       
    do i=1, 5
       x=3.14159  ! do something with x in fortran77
       call B()   ! new f90 code
    enddo
  end program main

  ! new features added here   
  subroutine new_code()
    use Bmod
    write(*,*) 'x in B=', x
  end subroutine new_code

但是我在编译时遇到错误:

 error #6401: The attributes of this name conflict with those made accessible by a USE statement.   [X]
    common /a/ x

一个简单的解决方案就是让所有人都能玩。但在我的情况下这是不允许的,因为它会修改旧代码。除了旧代码由几千个变量组成,这些变量分布在以旧式编写的几个常见块上。

2 个答案:

答案 0 :(得分:3)

您可以将公共块定义放在模块中。在这种情况下,您可以将两者结合使用,但必须小心如何访问它。

您无法在已通过模块访问它的任何单元中定义公共块。

  module Bmod
    real*8 x
    common /a/ x   ! old code                       
  end module Bmod

  program main
    real*8 x
    common /a/ x   ! old code                       
    do i=1, 5
       x=3.14159  ! do something with x in fortran77
       call new_code()   ! new f90 code
    enddo
  end program main

  ! new features added here   
  subroutine new_code()
    use Bmod
    write(*,*) 'x in B=', x
  end subroutine new_code

关于您的错误消息:

您显示的代码无效

首先从模块中导入符号x

use Bmod !x is in Bmod

然后你说它在一个命名的公共区块

common /a/ x  

你可以拥有一个或另一个,两者都没有任何意义。您可以使用模块变量,也可以使用公共块中的变量。

您不必一次删除所有公共区块。甚至不是一次整个公共块。但是,一旦将某个变量移动到某个模块,就不能同时将它放在公共块中。您可以一次使用一个变量将其从公共块中删除,并将其放置到模块中(如果您希望它在模块中)。

答案 1 :(得分:3)

如果你想改变声明变量的方式,你必须一直到处都这样做。

我认为你有这样的事情:

program common
    implicit none
    real*8 x
    common /a/ x
    x = 3.0
    call mysub()
    print *, x
end program common

subroutine mysub()
    implicit none
    real*8 x
    common /a/ x
    x = 4.0
end subroutine mysub

如果您现在想要将x的声明移到一个单独的模块中(不错的选择!),您必须始终如一地执行此操作。也就是说,你不能在模块中声明x,然后在程序中创建一个公共块的x部分。

最好的解决方案是完全删除公共块:

module mymod
    implicit none
    real*8 x
end module mymod

program common
    use mymod
    implicit none
    x = 3.0
    call mysub()
    print *, x
end program common

subroutine mysub()
    use mymod
    implicit none
    x = 4.0
end subroutine mysub

但是如果由于政治原因你必须保留COMMON块,你必须把它移到模块中:

module mymod
    implicit none
    real*8 x
    common /a/ x
end module mymod

program common
    use mymod
    implicit none
    x = 3.0
    call mysub()
    print *, x
end program common

subroutine mysub()
    implicit none
    real*8 x
    common /a/ x
    x = 4.0
end subroutine mysub

(我觉得这只是写得很脏......)

当然,如果模块中的两个xCOMMON块不相同,您可以随时在本地更改其名称:

use mymod, only: y => x

这会使模块的x可用y,同时保持公共x完整。

相关问题