Search code examples
memoryfortranfortran-common-block

What is actually happening in memory in Fortran common blocks?


I'm coming into Fortran with a heavy C background. It's all pretty straightforward, except the actual mechanisms of how common blocks work baffles me, and I can't find any place that describes them in detail.

Let's say I have the following common block:

COMMON/MYBLOCK/ A,B,C

As I understand this, this will set aside a chunk of memory that contains three...things, that aren't really associated with the names in the block, and in fact if If have this next code later in my source:

SUBROUTINE MYSUB(...)
...
COMMON/MYBLOCK/ X,Y,Z
...
END 

Then now X is associated with whatever used to be in A, and the same Y to B and Z to C.

So this means COMMON/MYBLOCK/ is...an array of void pointers when it's declared? There's no type associated with any of these pointers, so...memory is allocated when a value is assigned? What happens if I say A='A' in my main thread, but then in MYSUB I say A=3.141592? If I have a subroutine that I want to return a value into A by reference (because it's part of an external library), can I just say CALL MYSUB2(A) and count on the compiler to sort it out? Or do I need to call MYSUB2 on a local variable first, then assign that to A?

It's weird, Fortran is such a strongly typed language everywhere else, but common blocks are just like "do whatever you want, man, we don't do types here"...


Solution

  • You should not confuse what the standard language allows you and what you can get away with in existing compilers and what people use in various legacy codes.

    Common blocks are a place for static storage that can be accessed from various compilation units. The variables stored there are accessed using the common block name and the position (offset) of the variable inside the common block.

    Whether the common blocks end up in the .data segment .bss segment is an implementation detail for a particular platform. But in practice on the platforms common today, the common blocks will appear in one of those.

    It is not here for type punning. One may not reference the same memory location as different types. It shall be always accessed as a single type. You can get away using the same memory location as different types only if you separate the usage. You cannot write a real and read an integer.

    The variables stored in common blocks certainly DO have a type. The type may be declared explicitly or determined using the implicit typing rules.

     IMPLICIT NONE
     
     COMMON /BLOCK1/ A, B, C
     
     END
    

    will give you

    > gfortran common.f90 
    common.f90:3:18:
    
      COMMON /BLOCK1/ A, B, C
                      1
    Error: Symbol ‘a’ at (1) has no IMPLICIT type
    common.f90:3:21:
    
      COMMON /BLOCK1/ A, B, C
                         1
    Error: Symbol ‘b’ at (1) has no IMPLICIT type
    common.f90:3:24:
    
      COMMON /BLOCK1/ A, B, C
                            1
    Error: Symbol ‘c’ at (1) has no IMPLICIT type
    

    and you will have to declare the type of the variables explicitly.

    Without seeing anything more from your code we have to conclude that your variables are of type real by the implicit typing rules, unless an explicit IMPLICIT statement imposes different implicit typing rules.