From Free Pascal wiki
Revision as of 19:15, 23 September 2022 by Kai Burghardt (talk | contribs) (→‎Routine overloading: not possible for `cdecl` routines)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

English (en) suomi (fi) français (fr) русский (ru)

A routine is a re-usable piece of source code having a name (called an identifier) that performs some functionality. Pascal distinguishes between two kinds of routines: procedures and functions. Functions are capable of returning a result value, while procedures do not. In consequence functions can appear in expressions, but procedures cannot.

A routine that is part of an object or class is called a method. Properties of objects or classes can redirect read and/or write access to methods in that property or class handling the read or write request, if their signatures have a certain structure.

Routine declarations and definitions


A function is a routine that may return a value, and its signature indicates this. The signature of a function is as follows:

function *name*: *result*;


function *name* (*parameter list*): *result*;

The meaning of these terms will be explained below under Signature.


A procedure is a routine that cannot return a value. The signature of a procedure is as follows:

procedure *name*;


procedure *name* (*parameter list*);


The items in the signature are:

*name* is an identifier than gives the name of the routine.
*parameter list* (if one is included) is one or more parameters, separated by semicolons, describing each argument to be passed to the routine.
*result type* (for functions only) defines what type of result the function may return.


Routines may be parameterized, that means they can have arguments supplied to them when called. When introducing a new routine identifier a parameter list (one or more arguments) can be appended. For instance the following procedure signature tells the compiler, that doSomething requires an integer as first parameter.

procedure doSomething(const someParameter: integer);

The following procedure signature tells the compiler, That doSomethingelse requires a real as first parameter and an integer as second parameter.

procedure doSomethingelse(const someParameter: Real; SomeOtherParameter: Integer);

Default values

Parameters can become optional when they are supplied with a default value like so:

procedure doSomething(const someParameter: integer = 42);

Defining default values is only possible in {$mode objFPC} or {$mode Delphi}, and they are only for simple types.

Optional parameters if any, have to appear at the end of the formal parameter list. Consequently, mandatory parameters cannot appear after any optional parameter.

Parameter hints

While defining the formal parameters in front of each identifier(s), type tuple, the compiler can be supplied with additional hints. The compiler then can make further optimizations.

  • const informs the compiler, that the named parameter(s) won't be changed in the routine definition.
  • constref imposes further restrictions.

Parameter types

By default each routine receives an own copy of each parameter (value parameter).

  • If the routine is supposed to work on the original, that means on the variable as it exists in the place the routine is called, the modifier var will allow that. Thereby the named parameter becomes a variable parameter.
  • Furthermore, if {$modeswitch out+} (automatically set by various modes), the output parameter type out exists. The routine will not, or is not supposed to read from such parameters, but only write.

Routine overloading

Routines can be overloaded. That means, one and the same identifier can be associated with varying definitions provided the formal signatures differ.

Light bulb  Note: Routine overloading is not possible for routines having the cDecl calling convention modifier. The FPC implements routine overloading by name mangling [= encoding parameter data types in a modified version of the routine’s identifier]. However, cDecl will disable such.


In order to define a routine, its signature is followed by a block.

The parameters are available by their identifiers inside the statement-frame and nested routines. In functions additional identifiers are available, in order to set the function's return value.

Invoking routines

Routines are called by stating their identifiers, followed by the list of (mandatory) parameter literals or variables their types are compatible. Depending on the routine's type, i.e. either procedure or function, routine calls are only allowed as statements or in expressions, or even both.

Comparative remarks

The definition of a routine always concludes with a return-instruction. Thus the control flow is always handed back to the LOC the routine was invoked at. In contrast to that behavior, goto jumps can be abused to circumvent that “limitation”.

Every routine call is preceded by proper allocation of parameter values.