Next: Functions, Previous: Main Program Unit, Up: Debugging and Interfacing
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.