Latest Tweets

gfortran: compiling Fortran77 legacy code errors

Preamble

We all know that gfortran is the replacement, to an extend, for g77 old-days Fortran 77 compiler. And we do know as well that gfortran can deal with Fortran 77, 90 and 95 code. That means we can compile old Fortran 77 legacy code using this compiler without making a great effort. Or at least that was the theory. Lately, a professor working in my department was in need of compiling a five years-old legacy Fortran 77 code using gfortran. It did not work at all. Or, we have to admit, it looked that way.

Analysing the code-syntax

Gfortran compiler allows us to check the code syntax, in order to be sure it is all right before going further. That can be easily accomplished running gfortran with the -fsyntax-only flag. In order to get rid of all the warning messages to focus only on the errors, we decided to check its syntax adding the -w flag. Thus:

gfortran -w -fsyntax-only *.f 2>err

Then, we had a look at the generated file err, and we found basically two different kind of error messages:

Error: Symbol ‘nnmax’ at (1) has no IMPLICIT type

Error: Type of argument ‘a’ in call to ‘dreal’ at (1) should be COMPLEX(8), not INTEGER(4)

Because the second one was present almost on every single file and more than once, we had a look at the intrinsic routine dreal() first. It came to happen in gfortran, dreal() parameter had to be a COMPLEX*16 (or COMPLEX(8)), whereas in g77 it could be either an INTEGER, REAL or COMPLEX data types. Therefore, our compiler error message. All the code was calling dreal() using an INTEGER parameter instead of a COMPLEX one. That code could not be compiled using gfortran, because dreal() had changed slightly.

According to its reference, this intrinsic function was in charge of returning the real part for a given complex number Z in the form of a double. That same professor told me the main purpose of these calls to dreal() in the original legacy Fortran 77 code was just to do a typecast (from INTEGER to DOUBLE). Thus, that dreal() intrinsic function was not correctly chosen in the first place, that is, five years ago. It was mandatory to use DBLE instead, available in g77 as well as in gfortran compilers.

To demonstrate we can use DBLE() instead of DREAL() either in g77 or gfortran, we have compiled the old g77 compiler in a Debian Squeeze EM64T box:

     PROGRAM HELLOW
     INTEGER it
     it = 30
     WRITE(*, *) DBLE(it)
     END

We compiled this code using our g77 compiler:

LD_LIBRARY_PATH=/usr/local/g77/lib64 dble.f -o dble.e_g77 && LD_LIBRARY_PATH=/usr/local/g77/lib64 ./dble.e_g77

No errors, so the intrinsic call DBLE() was present in g77. Obviously, we could determine when this call was available in previous gcc releases. But at least it was in the GNU gcc 3.4.6 release.

Replacing calls to DREAL() for DBLE()

Using an editor, we changed all the calls to DREAL() for DBLE(). For example, doing so in our previous test Fortran 77 code we got just the same result:

30.0

Thus, it proved it was a matter of choosing the wrong intrinsic function at that time, because DBLE() has not changed at all between g77 and gfortran, thus offering high levels of compatibility.

After fixing these calls, the code could be compiled and ran, because the two old Fortran 77 legacy code files issuing the first error were not longer required.