Next: , Previous: Main Program Unit, Up: Debugging and Interfacing


13.2 Procedures (SUBROUTINE and FUNCTION)

Currently, g77 passes arguments via reference—specifically, by passing a pointer to the location in memory of a variable, array, array element, a temporary location that holds the result of evaluating an expression, or a temporary or permanent location that holds the value of a constant.

Procedures that accept CHARACTER arguments are implemented by g77 so that each CHARACTER argument has two actual arguments.

The first argument occupies the expected position in the argument list and has the user-specified name. This argument is a pointer to an array of characters, passed by the caller.

The second argument is appended to the end of the user-specified calling sequence and is named `__g77_length_x', where x is the user-specified name. This argument is of the C type ftnlen (see gcc/libf2c/g2c.h.in for information on that type) and is the number of characters the caller has allocated in the array pointed to by the first argument.

A procedure will ignore the length argument if `X' is not declared CHARACTER*(*), because for other declarations, it knows the length. Not all callers necessarily “know” this, however, which is why they all pass the extra argument.

The contents of the CHARACTER argument are specified by the address passed in the first argument (named after it). The procedure can read or write these contents as appropriate.

When more than one CHARACTER argument is present in the argument list, the length arguments are appended in the order the original arguments appear. So `CALL FOO('HI','THERE')' is implemented in C as `foo("hi","there",2,5);', ignoring the fact that g77 does not provide the trailing null bytes on the constant strings (f2c does provide them, but they are unnecessary in a Fortran environment, and you should not expect them to be there).

Note that the above information applies to CHARACTER variables and arrays only. It does not apply to external CHARACTER functions or to intrinsic CHARACTER functions. That is, no second length argument is passed to `FOO' in this case:

     CHARACTER X
     EXTERNAL X
     CALL FOO(X)

Nor does `FOO' expect such an argument in this case:

     SUBROUTINE FOO(X)
     CHARACTER X
     EXTERNAL X

Because of this implementation detail, if a program has a bug such that there is disagreement as to whether an argument is a procedure, and the type of the argument is CHARACTER, subtle symptoms might appear.