如何使用旧代码将新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
一个简单的解决方案就是让所有人都能玩。但在我的情况下这是不允许的,因为它会修改旧代码。除了旧代码由几千个变量组成,这些变量分布在以旧式编写的几个常见块上。
答案 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
(我觉得这只是写得很脏......)
当然,如果模块中的两个x
和COMMON
块不相同,您可以随时在本地更改其名称:
use mymod, only: y => x
这会使模块的x
可用y
,同时保持公共x
完整。