Reputation: 1366
How does one interface a new Fortran 90 module with old code with as little modification as possible? The idea is to use a "module" for new code in a subroutine while leaving old code with as little modification as possible (i.e leaving common blocks untouched).
To demonstrate what I intend to achieve, here is simple program:
Consider a simple program:
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
But I get an error while compiling:
error #6401: The attributes of this name conflict with those made accessible by a USE statement. [X]
common /a/ x
A simple solution is to get ride of common everywhere. But that is not allowed in my case as it will modify old code. Besides the old code consists of several thousand variables spread over several common blocks written in an old style.
Upvotes: 2
Views: 1390
Reputation: 60008
You can put the common block definition inside a module. In that case you can combine both, but you must be careful how you access it.
You cannot define the common block in any unit which has already access to it through the module.
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
Regarding your error message:
The code you show is invalid
You first import symbol x
from a module
use Bmod !x is in Bmod
and then you say it is in a named common block
common /a/ x
You can have one or the other, both don't make any sense. Either you have a module variable, or a variable from a common block.
You don't have to delete all common blocks at once. Not even a single whole common block at once. But once you move some variable to a module, you cannot have it in the common block at the same time. You can go with one variable at a time end delete it from the common block and place it to a module if you want it in a module.
Upvotes: 3
Reputation: 8140
If you want to change the way variables are declared, you have to do it everywhere consistently.
I assume you had something like this:
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
If you now want to move the declaration of x
into a separate module (good choice!), you have to do it consistently. That is, you cannot declare x
in the module, then in the program make the x
part of a common block.
The best solution would be to completely remove the common block:
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
But if for political reasons you have to keep the COMMON
block, you have to move it into the module:
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
(I feel dirty just writing this...)
Of course, if the two x
from the module and the COMMON
block are not the same, you can always change their names locally:
use mymod, only: y => x
This would make the module's x
available as y
, while keeping the common x
intact.
Upvotes: 3