Starting with Fortran 90, the language took a path of “safety” that began with type, kind, and rank (TKR) considerations. If those wishing to employ Fortran now cannot pay full heed to TKR, then there is little scope for further discourse.
As I tried to mention briefly upthread but which has been explained in quite a few literature source that have been authored since Fortran 90, the COMMON
facility in FORTRAN
with its semantics based primarily on storage association and hardly any numbered constraints leave much to be desired in terms of TKR safety. And given the needs of compatibility with FORTRAN 77
and earlier revisions, there is not much that could have been changed.
The use of COMMON
allowed code such as the following where TKR considerations can be circumvented in any number of ways:
! A subprogram with implicit interface making use of "global" data named 'dat'
subroutine sub1()
implicit double precision(a-h,o-z), integer(i-n)
common / dat / x, y, i, j, z
! Instructions employing x, y, i, and z
x = 1.0d0 ; y = 2.0d0 ; i = 3 ; j = 4; z = 4.0d0
end subroutine
! Another subprogram with implicit interface making use of "global" data
! named 'dat' differently
subroutine sub2()
dimension a(4), b(3)
common / dat / a, i, b
! Instructions employing b n, b
a = 0.0
i = 42
b = 1.0
end subroutine
! A main driver statically allocating memory for "global" data using integers
integer m(8)
common / dat / m
m = 0
call sub1()
print *, "main: following sub1, m = ", m, "; expected m(5) = 3"
call sub2()
print *, "main:: following sub2, m = ", m, "; expected m(5) = 42"
end
C:\Temp>gfortran -c sub1.f90
C:\Temp>gfortran -c sub2.f90
C:\Temp>gfortran -c f.f90
C:\Temp>gfortran f.o sub1.o sub2.o -o f.exe
C:\Temp>f.exe
main: following sub1, m = 0 1072693248 0 1073741824 3 4 0 1074790400 ; expected m(5) = 3
main:: following sub2, m = 0 0 0 0 42 1065353216 1065353216 1065353216 ; expected m(5) = 42
C:\Temp>
Given what’s possible with Fortran 2018, the above approach I would argue is equivalent to using a chainsaw without any blade guards.
Many a scientist and engineer has had problems with working with such code even though such programs were (and in some domains, are still) prevalent:
- they would clobber “global” data by working with inconsistent or wrong types,
- cause misalignment,
- have programs that lead to inconsistent or inaccurate results depending on program input data, and so forth.
This is one example of what I mean by error-prone that I came to know of whilst refactoring legacy code. Others can provide much better explanation and details than this, for my experience with COMMON
is read-only.
As readers can see with the example here, a programmer can continue using COMMON
if they so wish. But there are safer alternatives that can also yield portable and performant code. That’s what readers should preferably consider in their codes.