Call Modern Fortran from legacy code

Hi everyone, I was wondering if there is a way to call modern fortune routines from “legacy” codes. In particular, I am interested into the code Q-GCM, that my colleague is using, and he writes his routines with the 77 style. I was wondering if there was a simple way to write Modern Fortran procedures and call them from this code.

Let me know what you think, and thank you for your help

If the “modern fortran” routine is an external subprogram with arguments of intrinsic type within the f77 subset and that works with an implicit interface, then an old f77 program can call it in the usual way, even if the routine itself uses new features within. If the “modern fortran” procedure is a module procedure that is consistent with an implicit interface, then I think it can be called from the old f77 program if there is a bind(C,name='external_name') clause. You aren’t really doing any C interop, you are just using that feature to give a normal looking external_name to the procedure. Otherwise, the external symbol is embellished with the module name in a compiler-dependent way that the programmer does not control.

However, if the “modern fortran” procedure has dummy arguments that use modern features, such as derived types, pointer, allocatable, object-oriented attributes, and so on, than an explicit interface is required, and that requires the calling program to use parts of the language outside of the f77 subset.

@kimala,

What processor toolset(s) does your colleague use to build the program from the code? For example, what are the hardware and the OS, the compiler and linker names and versions?

Your first question has to be whether the processor toolset(s) used by your colleague are the same as or compatible with what you use?

The language aspect you ask is straightforward after this question is cleared up.

Unless your project and the compiler it is using really does restrict you to FORTRAN 77 (which I doubt or you wouldn’t be able to use the modern features at all) you can still use the modern features in fixed-format code. Something like the following works just fine.

      SUBROUTINE SOME_OLD_CODE(...)
      USE MY_MODULE
      ...
! Use something from the module
      ...
      END SUBROUTINE

Fortran modern features and Fortran source form are two separate things.

The free source form is certainly a “modern feature”, but writing MODULE units, USEing modules, derived types, overloading, etc., is not exclusive to it —The code you point to, actually has fixed source form code with USE statements.

If you’re using an f90+ compiler and your colleague is using an f77 one, or vice versa, then your only option to mix is through the linker, like @RonShepard suggested.

Otherwise, go ahead and mix source code forms as needed/wanted.

One common Fortran misconception is to think *.f means Fortran 77-, *.f90 means Fortran 90, *.f95 means Fortran 95, and so on.

The extension is just a convention provided by compiler vendors (*.f is usually interpreted as fixed source form. whereas *.f90 is interpreted as free source form; that’s all). I know of at least one compiler that already has a few Fortran 2023 features, but only accepts *.f and *,f90 as extensions (no *.f95*f23 allowed).

1 Like

Indeed. I am pretty sure there is some misunderstanding in this thread…

As others said, I guess you are talking about fixed-form source. Fixed-form sources can contain any Fortran feature, even Fortran 2023, as long as they are compiled with a compiler that implement it.

Consequently, even if this code currently uses only Fortran 77 features, you can in particular call any procedure written in Modern Fortran.

Many thanks to @PierU @jwmwalrus @everythingfunctional @FortranFan @RonShepard that replied.

I was suspecting that the code that I was linking was not FORTRAN 77 but rather a newer version in fixed form, but I wanted a second (and third, up to five) opinion (so I can also tell to my colleague to stop writing the code as it was F77 for crying out lout :sweat_smile: ).

Thank you again, I might come back with more questions if I fail in this task.

Maybe it’s pure F77, maybe not, but the point is that it doesn’t matter at all.

The main problem is that sometimes we use tools without deeply knowing the tool itself (this applies for me as well, with fortran, python and many others), so we build our knowledge step by step with use cases, but sometimes we also build bounds out of our mistakes without knowing.

When my colleague showed me that code I thought “wait, I don’t remember USE statements in my FORTRAN 77 book” but then he told me that he was not able to compile allocatable arrays so I trusted him. Yesterday we were discussing, and this “QGCM is FORTRAN 77” statement came out again, so I had a spare 5 minutes and wrote the question. Turns out that this morning, I actually put a simple real*8, allocatable, dimension(:) :: a in the code and it was compiling fine (with gfortran and no other libraries other than netcdf), so who knows what was happening before ¯\_(ツ)_/¯

It’s fun to find Blake’s “Mind-forg’d manacles” in fortran computing

If QCGM uses procedures with names longer than 6 characters, then it is not F77. Most compilers in the 80s also provided some extensions, like the famous MIL-STD-1753: Doctor Fortran in "Military Strength" - Doctor Fortran

I’ve seen this misconception before, where C and C++ library developers claim they cannot use Fortran modules, or C bindings, because they need to remain compatible with F77, and yet they ignore the procedure name length.

Adding modules to any new parts of the new program will very likely require some restructuring of the build process. (In CMake it should just work in principle.)

1 Like