Cannot remove COMMON block, despite setting global values

As stated in a previous ppost, my old FORTRAN code has a lot of COMMON statements; or did have.

I have successfully removed most of these simply by defining the variables within an included file (will be a module, but not yet). Where possible, I have included these within the parameters of the subroutine, thus reducing the number of globals - which is still insane!

Anyway, I have 1 remaining COMMON block that is used within 2 subroutines…

            common / rates / rpp, rhe3he3, rcno, r3a, r12a, r16a, rcc,  &
     &                       rlip, xpd, xpc, xpn, xpo, xpp23

I have checked and the variables within the common block only appear within the relevant two subroutines and the two common statements within both routines are identical.

I have created the same variables within the include file…

		double precision :: rpp, rhe3he3, rcno, r3a, r12a, r16a, rcc
		double precision :: rlip, xpd, xpc, xpn, xpo, xpp23

Yet, the code now generates incorrect data. The code runs fine but the results are wrong.

So, the variable values are not remaining the same (since the common block is the only part of the system I am ruling out at present).

What am I missing?

1 Like

Here a few ideas:

  • Have you checked that the variables in the include file (within a module)
    are actually used and have actually the type double precision.

  • Maybe you can create a “reduced” testcase to check what are the conditions that cause the error to happen

1 Like

Your descriptions are ambiguous and confusing, and providing parts of the real code would be helpful.

If you have variables declared in an include file, and that file is included in two different subprograms, and those variables are not in a common block or modules shared by the two subprograms, those variables are local variables and the two sets of local variables are separate and distinct.

For example, if the file my_inc.fi has a single line:

integer ijk

and you have two subroutines subA and subB in the same or separate source files:

subroutine subA()
include 'my_inc.fi'
...
end subroutine subA
!
subroutine subB()
include 'my_inc.fi'
...
end subroutine subB

the local variable ijk of subA is distinct from the local variable ijk of subB. Usually, such local variables are allocated dynamically on the stack, and portions of the stack used by a subroutine are reclaimed when the subroutine is exited. Likewise, having the same name does not imply any connection between variables of different program units.

2 Likes

Sorry for the ambiguous and confusing nature of my post; I try to provide the essential information and get this wrong on occasion (probably far more than I think I do).

However, you have answered my question!

I realised that the reason for the other systems working is that I have either now parsed the variables through to the subroutines or the common blocks exist within the include files.

I had, indeed, misinterpreted the use of the include file, which might, in part, explain why my attempts at getting the module to work have not borne the fruit I had hoped to.

Thank you.

1 Like

You are using Named Common. Different from unnamed common. When named common is unused, as in two subroutines but not main, then the variables become undefined. Try adding the Named Common statements in main to ensure the variables don’t become undefined.

1 Like

In response to John Campbell’s comment:

I quote from Watcom Fortran 77 language reference 6th edition page 37 (Section 2.13 COMMON statement, subsection 3) :
“Entities in named common blocks can become undefined after the execution of a RETURN or END statement; entities in blank common cannot. This situation can arise when all subprograms which refer to the named common block become inactive. … if the named common is referenced in the main program then this could never happen. … The SAVE statement should be used if entities in named common blocks must not become undefined.”
I don’t know the situation with more recent compilers.

This was from back in the Olden Days of overlaying code on non-virtual memory machines. It is probably not worth going into the details. But suffice it to say that these days module scope variables always have the SAVE attribute.

As @mecej4 says, simply declaring variables in an include file is NOT the same functionality as a common block. You must place the COMMON statements into the include files as well. (And this is a Good Thing so the same definition is used everywhere.) Best is to use F90+ modules. While you are transitioning to modules, you can place the include statements in modules - so that various subprograms can either USE the module or INCLUDE the include file.