如何在公共块和模块之间共享数据?
How to share data between a common block and a module?
如何以尽可能少的修改将新的 Fortran 90 模块与旧代码连接起来?这个想法是对子例程中的新代码使用 "module",同时尽可能少地修改旧代码(即保持公共块不变)。
为了演示我打算实现的目标,这里有一个简单的程序:
考虑一个简单的程序:
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
一个简单的解决办法是乘坐common everywhere。但这在我的情况下是不允许的,因为它会修改旧代码。此外,旧代码包含数千个变量,分布在几个以旧样式编写的公共块上。
您可以将公共块定义放在模块中。在那种情况下,您可以将两者结合起来,但您必须小心访问它的方式。
您不能在任何已经通过模块访问它的单元中定义公共块。
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
关于您的错误信息:
您显示的代码无效
您首先从模块
导入符号[=13=]
use Bmod !x is in Bmod
然后你说它在一个命名的公共块中
common /a/ x
你可以选择其中之一,两者都没有任何意义。您有一个模块变量,或者一个来自公共块的变量。
您不必一次删除所有公共块。一次甚至没有一个完整的公共块。但是一旦你将一些变量移动到一个模块中,你就不能同时将它放在公共块中。你可以一次只处理一个变量,如果你想把它放在一个模块中,就把它从公共块中删除,然后把它放到一个模块中。
如果你想改变声明变量的方式,你必须始终如一地做到这一点。
我假设你有这样的事情:
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
(我写这个感觉很脏...)
当然,如果模块和COMMON
块中的两个x
不一样,你可以随时在本地更改它们的名称:
use mymod, only: y => x
这将使模块的 x
可用作 y
,同时保持通用 x
不变。
如何以尽可能少的修改将新的 Fortran 90 模块与旧代码连接起来?这个想法是对子例程中的新代码使用 "module",同时尽可能少地修改旧代码(即保持公共块不变)。
为了演示我打算实现的目标,这里有一个简单的程序:
考虑一个简单的程序:
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
一个简单的解决办法是乘坐common everywhere。但这在我的情况下是不允许的,因为它会修改旧代码。此外,旧代码包含数千个变量,分布在几个以旧样式编写的公共块上。
您可以将公共块定义放在模块中。在那种情况下,您可以将两者结合起来,但您必须小心访问它的方式。
您不能在任何已经通过模块访问它的单元中定义公共块。
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
关于您的错误信息:
您显示的代码无效
您首先从模块
导入符号[=13=]use Bmod !x is in Bmod
然后你说它在一个命名的公共块中
common /a/ x
你可以选择其中之一,两者都没有任何意义。您有一个模块变量,或者一个来自公共块的变量。
您不必一次删除所有公共块。一次甚至没有一个完整的公共块。但是一旦你将一些变量移动到一个模块中,你就不能同时将它放在公共块中。你可以一次只处理一个变量,如果你想把它放在一个模块中,就把它从公共块中删除,然后把它放到一个模块中。
如果你想改变声明变量的方式,你必须始终如一地做到这一点。
我假设你有这样的事情:
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
(我写这个感觉很脏...)
当然,如果模块和COMMON
块中的两个x
不一样,你可以随时在本地更改它们的名称:
use mymod, only: y => x
这将使模块的 x
可用作 y
,同时保持通用 x
不变。