parameter; ...; parameter
Each parameter can start with a prefix (see below) describing how the parameters are passed, followed by a comma seperated list of one or more parameter_identifiers and an optional parameter_type.
procedure DoIt (var x, y, z: OneType; a, b: AnotherType; var q);
To understand parameter passing, first some definitions.
Technical note: Parameters are not always passed on the stack, they may also be passed in registers, especially on RISC machines.
The prefix defines how a variable is passed on the stack and how you can access the formal_parameter inside the procedure. The prefix can be one of:
procedure DoIt (x: SomeType);
Technical: The actual parameter is passed by value or reference, but if passed by reference, it is then copied to a local copy on the stack. Aliasing has no effect on x.
What it means: you can modify x inside the routine, but your
changes will not affect the actual parameter (and vice versa). The
actual parameter can be a constant or other immutable object, or a
protected or const variable.
procedure DoIt (protected x: SomeType);
Technical: The actual parameter is passed by value or reference, but
if passed by reference, it is then copied to a local copy on the
stack. Aliasing has no effect on x. protected
is a Extended
Pascal extension.
What it means: if you modify the actual parameter, this will not
affect x inside the routine. The actual parameter can be a
constant or other immutable object, or a protected or const
variable. You are forbidden from modifying x inside the routine.
procedure DoIt (var x: SomeType);
Technical: The actual parameter is passed by reference. Aliasing will definitely change x.
What it means: modifications to x inside the routine will change the actual parameter passed in. The actual parameter must be an addressable L-value (ie, it must be something you can take the address of and assign to).
A parameter of this kind is called variable parameter and internally
corresponds to an L-value pointer (to the specified type identifier
if any). This declaration is necessary if the parameter is to be
modified within the routine and to hold its value still after
return.
procedure DoIt (const x: SomeType);
Technical: The actual parameter is passed by value or reference.
The compiler will make a copy of the actual parameter to have
something it can address if the actual parameter is not addressable.
You are forbidden from modifying x inside the routine, and
therefore you cannot modify the actual parameter. Aliasing may or
may not change x. const
is a Borland Pascal extension.
What it means: You can pass any R-value. You cannot modify x
inside the routine. If you change the actual parameter while inside
the routine, x will have an undefined value.
procedure DoIt (protected var x: SomeType);
Technical: The actual parameter is passed by reference. The compiler will never make a copy of the actual parameter. You are forbidden from modifying x inside the routine, and therefore you cannot modify the actual parameter. Aliasing will definitely change x.
What it means: You can pass anything addressable. You cannot modify x inside the routine. If you change the actual parameter while inside the routine, x will change as well.
In GPC, the protected var
mode guarantees that the parameter
is always passed by reference, making it the correct choice for
calling C routines with const pointer parameters.
If you omit the formal parameter type specification, then any type may be passed to that parameter. Generally this is a bad idea, but occasionally it can be useful, especially for low level code.
As an Extended Pascal extension, you can also declare procedural parameters directly:
procedure parameter_identifier
or:
function parameter_identifier: parameter_identifier_result_type
Example for parameter lists:
program ParameterDemo; procedure Foo (var Bar; var Baz: Integer; const Fred: Integer); procedure Glork1 (function Foo: Integer; procedure Bar (Baz: Integer)); begin Bar (Foo) end; begin Baz := Integer (Bar) + Fred end; var a, b, c: Integer; begin Foo (a, b, c) end.