A function definition includes the code for the function. Function definitions can appear in any order, and in one source file or several, although a function cannot be split between files. Function definitions cannot be nested.
A function definition has the following syntax:
declaration-specifiers(opt) declarator declaration-list(opt) compound-statement
By default, the storage-class-specifier is
extern
. The static
specifier is also
allowed. See Section 2.10 for more
information on storage-class specifiers.
ANSI allows the type-qualifier to be const
or
volatile
, but either qualifier applied to a function
return type is meaningless, because functions can only return
rvalues and the type qualifiers apply only to lvalues.
The type-specifier is the data type of the value returned
by the function. If no return type is specified, the function is
declared to return a value of type int
. A function
can return a value of any type except "array of type"
or "function returning type". Pointers to arrays and
functions can be returned. The value returned, if any, is specified
by an expression in a return
statement. Executing a
return
statement terminates function execution and
returns control to the calling function. For functions that return a
value, any expression with a type compatible with the function's
return type can follow return
using the following
format:
return expression;
If necessary, the expression is converted to the return type of the function. Note that the value returned by a function is not an lvalue. A function call, therefore, cannot constitute the left side of an assignment operator.
The following example defines a function returning a character:
char letter(char param1) { . . . return param1; }
The calling function can ignore the returned value. If no expression
is specified after return
, or if a function terminates
by encountering the right brace, then the return value of the
function is undefined. No value is returned in the case of a
void
function.
If a function does not return a value, or if the function is always
called from within a context that does not require a value, a return
type of void
should be specified:
void message() { printf("This function has no return value."); return; }
Specifying a return type of void
in a function
definition or declaration generates an error under the following
conditions:
return
statement.
void
function is called in a context
that requires a value, an error occurs at the function call
site.
f1
in the following example:
int f1(char p2)
In this example, f1
is a "function returning
int
". A declarator can also be a more complex
construct, as in the following example:
int (*(*fpapfi(int x))[5])(float)
In this example, fpapfi
is a "function (taking an
int
argument) returning a pointer to an array of
five pointers to functions (taking a float
argument)
returning int
". See Chapter 4 for information on specific declarator syntax.
The declarator (function) need not have been previously declared. If the function was previously declared, the parameter types and return type in the function definition must be identical to the previous function declaration.
The declarator can include a list of the function's parameters.
In DEC C, up to 253
parameters can be specified in a comma-separated list enclosed
in parentheses. Each parameter has the auto
storage class by default, although register
is also
allowed. There is no semicolon after the right parenthesis of the
parameter list.
There are two methods of specifying function parameters:
int f1(char a, int b) { function body }
int f1(a, b) char a; int b; { function body }
Any undeclared parameters are assumed to be of type
int
.
A function definition with no parameters is defined with an empty parameter list. An empty parameter list is specified in either of two ways:
void
if the prototype style
is used. For example:
char msg(void) { return 'a'; }
char msg() { return 'a'; }
A function defined using the prototype style establishes a prototype for that function. The prototype must agree with any preceding or following declarations of the same function.
A function defined using the old style does not establish a prototype, but if a prototype exists because of a previous declaration for that function, the parameter declarations in the definition must exactly match those in the prototype after the default argument promotions are applied to the parameters in the definition.
Avoid mixing old style and prototype style declarations and definition for a given function. It is allowed but not recommended.
See Section 5.6 for more information on function parameters and arguments. See Section 5.5 for more information on function prototypes.
return
statements can be included, but they are not
required.