12.5 Parameter Passing
GPC supports a lot of funny things in parameter lists: value and
reference, protected and const parameters, strings and
other schemata with specified or unspecified discriminants,
conformant and open arrays, objects, procedural parameters, untyped
reference parameters, etc. All this requires sophisticated
type-checking; the responsible function is
convert_arguments() in the source file typecheck.c.
Every detail can be looked up from there.
Some short notes about the most interesting cases follow.
- Conformant arrays:
- First, the array bounds are passed (an even number of parameters of
an ordinal type), then the address(es) of the array(s) themselves.
- Procedural parameters:
- These need special care because a function passed as a parameter can
be confused with a call to the function whose result is then passed
as a parameter. See also the functions maybe_call_function()
and probably_call_function() in expressions.c.
- Chars:
- According to ISO 10206 Extended Pascal, formal char parameters
accept string values. GPC does the necessary conversion implicitly.
The empty string produces a space.
- Strings and schemata:
- Value parameter strings and schemata of known size are really passed
by value. Value parameter strings and schemata of unknown size are
passed by reference, and GPC creates temporary variable to hold a
copy of the string.
- CString parameters:
- GPC implicitly converts any string value such that the address of
the actual string data is passed and appends a Chr (0)
terminator when necessary.
- const parameters:
- If a constant value is passed to a const parameter, GPC
assigns the value to a temporary variable whose address is passed.
Exception: Small types (whose size is known and not bigger than that
of a pointer) as well as all integer, real and complex types are
passed by value.
- Untyped parameters:
- These are denoted by var foo or var foo: Void and are
compatible to C's void * parameters; the size of such
entities is not passed. Maybe we will change this in the
future and pass the size for var foo parameters whereas
var foo: Void will remain compatible to C. (Same with
const instead of var.)