5.3 Function Definitions

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:

function-definition:

declaration-specifiers(opt) declarator declaration-list(opt)
compound-statement
declaration-specifiers
The declaration-specifiers (storage-class- specifier, type-qualifier, and type- specifier) can be listed in any order. All are optional.

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:

declarator
The declarator specifies the name of the function being declared. A declarator can be as simple as a single identifier, such as 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:

A function definition with no parameters is defined with an empty parameter list. An empty parameter list is specified in either of two ways:

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.

compound-statement
The compound-statement is the group of declarations and statements surrounded by braces in a function or loop body. This compound statement is also called the function body. It begins with a left brace ({) and ends with a right brace (}), with any valid C declarations and statements in between. One or more return statements can be included, but they are not required.


Previous Page | Next Page | Table of Contents | Index