Search code examples
fortranintel-fortran

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.


Solution

  • 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.