I’ve been coding Fortran professionally for about a year and a half now, but the legacy code doesn’t use any features of modern Fortran, so I’m very new in this regard. My experience is in languages like C#, Kotlin and TypeScript.
Advice on how to create “overloads” of functions on Stack Overflow and right here states I must write something like this
module procedure foo, bar, baz
With the definitions of
baz in the
contains portion of a module. My question is, what does this actually do? I’ve struggled to find documentation on the “module procedure” statement, and interfaces in general. I understand this allows someone to write
call the_thing_callers_use(1, 2, 3)
But what actually goes on? How does it “match” the real function to the interface (if that’s even an appropriate description of what happens)? How do dummy arguments work? How type safe is it? Do
baz need to have the same return type? Are
baz now “private”?
I’m more looking for general information, but my specific use case involves me wanting to declare a second, double precision function with the same name and arguments as an existing single precision one in the library I’m working on. I thought I could change the actual name of the function and create an interface to not affect existing callers. (Most of the application is legacy and uses single precision, I’m using double precision in a specific portion and new code). Any help here is much appreciated.
The compiler matches the type, kind, and rank (TKR) of the argument list with the possible routines, and it selects the one that matches. This means that the TKR of the various possible routines must be distinct.
Welcome to this forum.
Re: “I’ve been coding Fortran professionally for about a year and a half now, but the legacy code doesn’t use any features of modern Fortran, so I’m very new in this regard”, hopefully you will find the Learning section at the parent site of this forum, fortran-lang.org helpful:
Learn — Fortran Programming Language
Re: “I’ve struggled to find documentation on the “module procedure” statement, and interfaces in general” please note with Fortran, as things stand now, a good place to start for Fortran language semantics is the books (also as e-books), especially “Modern Fortran Explained”. Also for developing modern applications, consider the book by @milancurcic
Immediately for “module procedure” you can consider compiler vendor sites and their developer reference guides such as with Intel Fortran and IBM XL Fortran .
Hi @adamyakes, and welcome!
The three procedures in your example must be distinguishable somehow, so that the compiler will know which one to call depending on the caller’s arguments. For example the third argument in
foo might be integer, while it’s real in
bar, and an array of 2 integers in
baz; In this case:
call the_thing_callers_use(1, 2, 3) will call
call the_thing_callers_use(1, 2, 3.) will call
call the_thing_callers_use(1, 2, [3, 4]) will call
In other words, at least one argument must be different (or even absent). All module procedures must be either subroutines or functions (you can’t mix both as module procedures). Assuming the module is
private, the procedures are also
private, in the sense the calling program has no access to them, it just has access to the generic
the_thing_callers_use (provided this one is
public, of course.)
Also note not all of them must be
module procedures. For example,
baz might be declared in another module; in this case it will be included in the interface as
procedure baz, not
module procedure baz.
It is a very efficient mechanism to create generic procedures. In many cases, one can achieve the same functionality with just one procedure having
optional arguments. However interfacing module procedures is often preferable.