When a FORTRAN program calls a subprogram, it is possible for the value of any of its arguments to be altered by that subprogram. In the case of C, a function cannot return modified values of arguments to the calling routine if what is passed is the value of the argument. If a C function is to modify one of its argument, then the address must be a pointer to the value to be modified rather than the actual value. Consequently in C functions that are designed to be called from FORTRAN, all function arguments should be treated as though the address of the actual argument had been passed, not its value. This means that the arguments should be referenced as *arg from within the C function and not directly as arg. This may seem odd to a FORTRAN programmer, but is natural to a C programmer.
To ensure that there always exists a pointer to each dummy argument, the first lines of code in the body of any C function that is to be called from FORTRAN should be GENPTR macros for each of the function arguments. The macros GENPTR_type always result in there being a C variable of type ``pointer to type'' for all non-character variables. For example, GENPTR_INTEGER(first) ensures that there will be a variable declared as int *first. On all current types of system, this macro will actually be null since the pointer is available directly as an argument. However, the macro should be present to guard against future computers working in a different way. For example, if a particular system passed FORTRAN variables by value rather than by reference, then this macro would construct the appropriate pointer.
Character arguments are different in that the GENPTR macro ensures that there are two variables available, one of type ``pointer to char'' that points to the actual character data, and one of type int that is the length of the character variable. The name of the variable that holds the length of the character string is constructed by appending ``_length'' to the name of the character variable. For example, if a function is declared to have a dummy argument with the macro CHARACTER(ch) and a corresponding TRAIL(ch), then after the execution of whatever the macro GENPTR_CHARACTER(ch) expands into, there will be a ``pointer to character'' variable called ch and an integer variable called ch_length. Although the length of a character variable is directly accessible through the int variable ch_length, it is better to pass the length of the character variable explicitly if maximum portability is sought. This is because, although it works on all currently supported platforms, it may not be possible to gain access to the length on some machines.
It is important to remember that what is available after the execution of what a GENPTR macro expands into will be a pointer to the dummy argument, not a variable of numeric or character type. Consequently the body of the code should refer to it as *arg and not as arg. In a long C function, it may be worth copying scalar arguments into local variables to avoid having to remember to put the * on each reference to an argument. If the variable is changed in the function, then it should of course be copied back into the argument at the end of the function. Alternatively you could define C macros to refer to the pointers, such as
#define STATUS *status
Note that although ANSI C will allow the above as status and STATUS are distinct names, you should beware of the possibility of a computer that does not have lower case characters. Such machines used to exist in abundance, but at present, this does seem a remote possibility.
Array arguments should have pointers generated (if necessary) by using the
macros. All arrays are handled by these macros.
CNF and F77 Mixed Language Programming -- FORTRAN and C