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.