Notes on Fortran and ITAPS interfaces¶
This is just a chain of conciousness set of issues I've run into (I am sure others have too) compiling and linking Fortran clients with iMesh implementations.
Fortran Header Generation tool (mkforth)¶
We have a perl script in the tools directory,
mkforth, that is designed to read an existing C header file and produce the essential Fortran header file. For the most part, this is a trivial mapping. However, there are issues with how
#include directives in original C file make it through. iMeshP includes MPI header file, mpi.h, due to reference to
MPI_Comm datatype. However, that is not needed in the Fortran header file. So, mkforth ignores any non-ITAPS include files. In addition, if an ITAPS header file is referenced from a C header file, its fortran equivalent has to be referenced from the generated Fortran header (e.g.
#include "iBase.h" in C iMesh.h translates to
#include "iBase_f.h" in iMesh_f.h)
C Pre-Processor and Fortran Source Code¶
So far, we've exploited cpp to handle some issues with the fortran interface. For example, in a fortran header file, we have something like...
#define iMesh_Instance integer*8There are a variety of limitations and issues with using the C Pre-Processor on Fortran source code.
- Google the issue and you'll learn about this.
- GNU products don't automatically run
cppon fortran sources. You have to either explicitly tell it to or name the file such that it has a
.Fextension as in
- When CPP is invoked by compiler automatically, it uses
-traditional-cppmode and may also use
-traditional-cppmeans you can't use any macros that use
#(token stringification) or
##(token pasting) CPP operators.
-undefmeans that none of the symbols the GNU C compiler ordinarily defines, such as
__SIZEOF_POITNER__, for example, are not defined.
- Macro substitutions can change the length of a line. Since non-free-form Fortran language is sensitive to line length issues, if any macro substitutions increase the line length (e.g. the replacement text is longer than the text being replaced), its possible the line length could run beyond fortran limit cause compilation errors.
- The solution, of course, is to ensure that all such macros' replacement text is less-than or equal in length to the text being replaced.
- The line-formatting of CPP statements in source files prior to running cpp on the files isn't an issue. The CPP statements need not obey Fortran line formatting requirements. However, after all CPP is completed, the resulting files must obey Fortran line formatting.
ITAPS Interface Pointers and Fortran¶
Fortran 77 didn't support pointers. An extension to Fortran 77, also known as cray pointers, was created to handle pointers in Fortran 77. The new
pointer statement was added to the language to support them. With GNU compilers, you have to invoke the compiler with
-fcray-pointer if you want support for pointers.
In Fortran, a pointer involves two variables, the pointer and the pointee. This is somewhat analagous C language where
char *p defines
p to be a pointer and then
*p is the pointee. But, in Fortran, these two parts of a pointer are actually different program variables defined with a
pointer statements as in
integer rpents integer*80 ents pointer (rpents, ents)
In the above,
rpents is the pointer and
ents is the pointee. it turns out the
integer rpents statement is not necessary and can actually lead to problems if the sizes of
pointer datatypes are different. It is more portable to allow the compiler to determine correct size of the pointer. But, to do this, you cannot have an
implicit none statement. In addition, in ITAPS interfaces we need to support two-levels of indirection. That is pointers to pointers to data. And, it still isn't clear to me how to support that using an implicit approach to defining the pointer types.
POINTER_SIZE symbol defined by ITAPS header files¶
For now, we've taken to requiring the client to explicitly set size of a pointer to either
integer by using something like
FCFLAGS=-DPOINTER_SIZE=8 prior to compiling Fortran ITAPS code.
The GNU C compiler defines
__SIZEOF_POINTER__ symbol and it would be nice to rely upon that to bootstrap the
POINTER_SIZE setting. However, I have yet to be able to find
__SIZEOF_POINTER__ defined while processing a
.F Fortran file. Somehow, the definition of this symbol is being turned off (maybe by GNU's automatic invokation of cpp with