2

In the Fortran 77 code , there is a combination use of common block and equivalence statement. For example,

    common  /X/ a,b,c,d
    dimension arr(4)
    equivalent(arr(1),a)

Can anybody provide a feasible solution that convert this kind of Fortran 77 code into Fortran 90 code?

AstroCB
  • 12,337
  • 20
  • 57
  • 73
witrus
  • 297
  • 1
  • 3
  • 13
  • 1
    The easiest way consists in doing nothing because this kind of F77 programming is still OK in F90, F2003, F2008 ... – Francois Jacq Jun 07 '13 at 10:13
  • is it really safe to assume the common variables are contiguous in memory? This strikes me as poor style even if it probably works most of the time. – agentp Jun 09 '13 at 13:48
  • 1
    @george Safe. The equivalence statement specifies storage association between the storage sequence established by the common statement and the storage sequence of the elements of the array. Layout in memory is an implementation detail, but the observable behaviour has to be as-if a contiguous chunk of memory was used. – IanH Jun 10 '13 at 01:54
  • @IanH thanks - I see this is clearly spelled out in the standard. – agentp Jun 10 '13 at 16:12
  • This may be useful if you want to set about replacing the scalars with array elements: you can (one program unit at a time) put the array in the common and equivalance(a,arr(1)) (b,arr(2)) , etc. Then set about carefully replacing scalars with explicit array elements. – agentp Jun 10 '13 at 16:37

1 Answers1

3

I assument that you mean an equivalence statement. This causes the named variables to share storage.

It might not be easy. There are several possible approaches depending on how the variables are used.

With the equivalence statement the various variables are automatically updated when their corresponding variable is changed since they occupy the same storage. Whenever b is changed a(2) automatically changes, etc. Whenever a(3) is changed, c automatically changes, etc.

You could make all of the variables into module variables -- the Fortran 90 way of having global variables. Omitting the equivalence statement they no longer share storage. Then you could simply write a(2) = b after any change to b, b = a(2) after any change to a(2), etc. But this requires that you identify every place in the program in which any of these variables change, and that one continue to follow this method when the program is modified. Which might not be easy.
Writing a(2) = b, etc., supposes that the variables are of the same type. If they are not, the Fortran 90 equivalent of equivalence is the transfer intrinsic function.

There are two better solutions depending on what the code is doing with the variables. If the program is really transferring info with the equivalence statement, then see if you can rewrite the code to use only one set of variable names. Replace the other name where ever it is used. This would only possible only if the types are the same.

If the program is using the equivalence to overlay variables that are not simultaneously used to conserve memory, then it is easier. In this case you can eliminate the equivalence statement and make the variables module variables instead of common and don't have additional work to do. And maybe they don't have to be global variables anymore. If one subroutine was using the other set, and another the other, and the common and equivalence was only a way of saving storage, you could make them into local variables.

The best solution depends on understanding the particular program.

I consider equivalence pernicious ... its worth a good amount of effort to get rid of. Still, if too deeply embedded into a large program, it might be very difficult.

M. S. B.
  • 28,968
  • 2
  • 46
  • 73
  • I need to update variables in common block.And I need to write these variables to the file using the array arr(since arr share the same memory space as the variables in common block).How can this be effectively implemented? – witrus Jun 07 '13 at 05:49
  • If the array is only used for writing, you can replace it in the code. `write (...) arr` is equivalent to `write (...) a, b, c, d`. For an unformatted write if the variables are of the same length or for a formatted write if the variables are of the same type. – M. S. B. Jun 07 '13 at 06:24
  • I come up with a scheme,to transform the variables in common block to be pointer variables in a module.Then in the main program define a target array.Such that in a module I define `integer,pointer ::a=>null(),b=>null(),c=>null()`,then in main program I define target array `integer,dimensions(3),target ::arr`,`a=>arr(1),b=>arr(2),c=>arr(3)`,then write variable a,b,c to a file using arr.Does this scheme feasible.I think my scheme is awful in some sense. – witrus Jun 07 '13 at 06:50
  • 1
    Why do you think that you need an array in order to write the variables to a file? Just directly write the scaler variables, as a list after the "write". I could understand if you had a huge number of scalers, but that would probably mean that you should have an array instead of the scaler variables. – M. S. B. Jun 07 '13 at 09:32
  • @wirtus yes it could work, another question is whether it's worth or not as M.S.B. said. – aka.nice Jun 07 '13 at 16:43