A function definition associates the function body (a sequence of declarations and statements) with the function name and parameter list. Unlike function declaration, function definitions are allowed at file scope only (there are no nested functions).
C supports two different forms of function definitions:
attr-spec-seq(optional) specifiers-and-qualifiers parameter-list-declarator function-body | (1) | |
specifiers-and-qualifiers identifier-list-declarator declaration-list function-body | (2) | (until C23) |
where.
attr-spec-seq | - | (C23)an optional list of attributes, applied to the function |
specifiers-and-qualifiers | - | a combination of
|
parameter-list-declarator | - | a declarator for a function type which uses a parameter list to designate function parameters |
identifier-list-declarator | - | a declarator for a function type which uses a identifier list to designate function parameters |
declaration-list | - | sequence of declarations that declare every identifier in identifier-list-declarator. These declarations cannot use initializers and the only storage-class specifier allowed is register . |
function-body | - | a compound statement, that is a brace-enclosed sequence of declarations and statements, that is executed whenever this function is called |
int max(int a, int b) { return a>b?a:b; } double g(void) { return 0.1; }
int max(a, b) int a, b; { return a>b?a:b; } double g() { return 0.1; }
As with function declarations, the return type of the function, determined by the type specifier in specifiers-and-qualifiers and possibly modified by the declarator as usual in declarations, must be a complete non-array object type or the type void
. If the return type would be cvr-qualified, it is adjusted to its unqualified version for the purpose of constructing the function type.
void f(char *s) { puts(s); } // return type is void int sum(int a, int b) { return a+b: } // return type is int int (*foo(const void *p))[3] { // return type is pointer to array of 3 int return malloc(sizeof(int[3])); }
As with function declarations, the types of the parameters are adjusted from functions to pointers and from arrays to pointers for the purpose of constructing the function type and the top-level cvr-qualifiers of all parameter types are ignored for the purpose of determining compatible function type.
Unlike function declarations, unnamed formal parameters are not allowed (otherwise, there would be conflicts in old-style (K&R) function definitions), they must be named even if they are not used within the function. The only exception is the special parameter list | (until C23) |
Formal parameters may be unnamed in function definitions, because old-style (K&R) function definitions has been removed. Unnamed parameters are inaccessible by name within the function body. | (since C23) |
int f(int, int); // declaration // int f(int, int) { return 7; } // Error until C23, OK since C23 int f(int a, int b) { return 7; } // definition int g(void) { return 8; } // OK: void doesn't declare a parameter
Within the function body, every named parameter is an lvalue expression, they have automatic storage duration and block scope. The layout of the parameters in memory (or if they are stored in memory at all) is unspecified: it is a part of the calling convention.
int main(int ac, char **av) { ac = 2; // parameters are lvalues av = (char *[]){"abc", "def", NULL}; f(ac, av); }
See function call operator for other details on the mechanics of a function call and return for returning from functions.
__func__Within every function-body, the special predefined variable static const char __func__[] = "function name"; This special identifier is sometimes used in combination with the predefined macro constants | (since C99) |
The argument list must be explicitly present in the declarator, it cannot be inherited from a typedef.
typedef int p(int q, int r); // p is a function type int(int, int) p f { return q + r; } // Error
In C89, specifiers-and-qualifiers was optional, and if omitted, the return type of the function defaulted to In addition, old-style definition didn't require a declaration for every parameter in declaration-list. Any parameter whose declaration was missing had type max(a, b) // a and b have type int, return type is int { return a>b?a:b; } | (until C99) |
The following behavior-changing defect reports were applied retroactively to previously published C standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
DR 423 | C89 | the return type might be qualified | the return type is implicitly disqualified |
C++ documentation for Function definition |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/function_definition