5.5 Function Prototypes

A function prototype is a function declaration that specifies the data types of its arguments in the parameter list. The compiler uses the information in a function prototype to ensure that the corresponding function definition and all corresponding function declarations and calls within the scope of the prototype contain the correct number of arguments or parameters, and that each argument or parameter is of the correct data type.

Prototypes are syntactically distinguished from the old style of function declaration. The two styles can be mixed for any single function, but this is not recommended. The following is a comparison of the old and the prototype styles of declaration:

Old style:

The DEC C compiler will warn about old-style function declarations only in strict ANSI standard mode, or when the check compiler option is specified.

Prototype style:

5.5.1 Prototype Syntax

A function prototype has the following syntax:


   declaration-specifiers(opt) declarator;

The declarator includes a parameter type list, which can consist of a single parameter of type void . In its simplest form, a function prototype declaration might have the following format:

storage_class(opt) return_type(opt) function_name (
type(1) parameter(1), ..., type(n) parameter(n) );

Consider the following function definition:

char  function_name( int lower, int *upper, char (*func)(), double y )
{ }

The corresponding prototype declaration for this function is:

char  function_name( int lower, int *upper, char (*func)(), double y );

A prototype is identical to the header of its corresponding function definition specified in the prototype style, with the addition of a terminating semicolon (;) or comma (,), as appropriate (depending on whether the prototype is declared alone or in a multiple declaration).

Function prototypes need not use the same parameter identifiers as in the corresponding function definition because identifiers in a prototype have scope only within the identifier list. Moreover, the identifiers themselves need not be specified in the prototype declaration; only the types are required.

For example, the following prototype declarations are equivalent:

char  function_name( int lower, int *upper, char (*func)(), double y );
char  function_name( int a, int *b, char (*c)(), double d );
char  function_name( int, int *, char (*)(), double );

Though not required, identifiers should be included in prototypes to improve program clarity and increase the type-checking capability of the compiler.

Variable-length argument lists are specified in function prototypes with ellipses. At least one parameter must precede the ellipses. For example:

char  function_name( int lower, ... );

Data-type specifications cannot be omitted from a function prototype.

5.5.2 Scope and Conversions

Prototypes must be placed appropriately in each compilation unit of a program. The position of the prototype determines its scope. A function prototype, like any function declaration, is considered within the scope of a corresponding function call only if the prototype is specified within the same block as the function call, any enclosing block, or at the outermost level of the source file. The compiler checks all function definitions, declarations, and calls from the position of the prototype to the end of its scope. If you misplace the prototype so that a function definition, declaration, or call occurs outside the scope of the prototype, any calls to that function behave as if there were no prototype.

The syntax of the function prototype is designed so that you can extract the function header of each of your function definitions, add a semicolon (;), place the prototypes in a header, and include that header at the top of each compilation unit in your program. In this way, function prototypes are declared to be external, extending the scope of the prototype throughout the entire compilation unit. To use prototype checking for C library function calls, place the #include preprocessor directives for the .h files appropriate for the library functions used in the program.

It is an error if the number of arguments in a function definition, declaration, or call does not match the prototype.

If the data type of an argument in a function call does not match the corresponding type in the function prototype, the compiler tries to perform conversions. If the mismatched argument is assignment- compatible with the prototype parameter, the compiler converts the argument to the data type specified in the prototype, according to the argument conversion rules (see Section 5.6.1).

If the mismatched argument is not assignment-compatible with the prototype parameter, an error message is issued.

Previous Page | Next Page | Table of Contents | Index