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
`egcs/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.