wander95
wander95

Reputation: 1366

How to share data between a common block and a module?

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

Answers (2)

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

chw21
chw21

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

Related Questions