summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Ffunction_declaration.html
blob: af2619d7598bdc910a72e2bd9376727f61e00117 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    <h1 id="firstHeading" class="firstHeading">Function declarations</h1>            <p>A function declaration introduces an <a href="identifier" title="c/language/identifier">identifier</a> that designates a function and, optionally, specifies the types of the function parameters (the <i>prototype</i>). Function declarations (unlike <a href="function_definition" title="c/language/function definition">definitions</a>) may appear at block scope as well as file scope.</p>
<h3 id="Syntax"> Syntax</h3> <p>In the <a href="declarations" title="c/language/declarations">declaration grammar</a> of a function declaration, the <span class="t-spar">type-specifier</span> sequence, possibly modified by the declarator, designates the <i>return type</i> (which may be any type other than array or function type), and the <span class="t-spar">declarator</span> has one of three forms:</p>
<table class="t-sdsc-begin">  <tr class="t-sdsc"> <td> <span class="t-spar">noptr-declarator</span> <code>(</code> <span class="t-spar">parameter-list</span> <code>)</code> <span class="t-spar">attr-spec-seq</span><span class="t-mark">(optional)</span> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td>
</tr>  <tr class="t-sdsc"> <td> <span class="t-spar">noptr-declarator</span> <code>(</code> <span class="t-spar">identifier-list</span> <code>)</code> <span class="t-spar">attr-spec-seq</span><span class="t-mark">(optional)</span> </td> <td> (2) </td> <td> <span class="t-mark-rev t-until-c23">(until C23)</span> </td>
</tr>  <tr class="t-sdsc"> <td> <span class="t-spar">noptr-declarator</span> <code>(</code> <code>)</code> <span class="t-spar">attr-spec-seq</span><span class="t-mark">(optional)</span> </td> <td> (3) </td> <td class="t-sdsc-nopad"> </td>
</tr> 
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">noptr-declarator</span> </td> <td> - </td> <td> any <a href="declarations#Declarators" title="c/language/declarations">declarator</a> except unparenthesized pointer declarator. The identifier that is contained in this declarator is the identifier that becomes the function designator. </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">parameter-list</span> </td> <td> - </td> <td> either the single keyword <code>void</code> or a comma-separated list of <i>parameters</i>, which may end with an <a href="variadic" title="c/language/variadic">ellipsis parameter</a> </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">identifier-list</span> </td> <td> - </td> <td> comma-separated list of identifiers, only possible if this declarator is used as part of old-style <a href="function_definition" title="c/language/function definition">function definition</a> </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">attr-spec-seq</span> </td> <td> - </td> <td> <span class="t-mark-rev t-since-c23">(C23)</span>an optional list of <a href="attributes" title="c/language/attributes">attributes</a>, applied to the function type </td>
</tr>
</table> <div class="t-li1">
<span class="t-li">1)</span> New-style (C89) function declaration. This declaration both introduces the function designator itself and also serves as a function prototype for any future <a href="operator_other#Function_call" title="c/language/operator other">function call expressions</a>, forcing conversions from argument expressions to the declared parameter types and compile-time checks for the number of arguments. <div class="c source-c"><pre data-language="c">int max(int a, int b); // declaration
int n = max(12.01, 3.14); // OK, conversion from double to int</pre></div>
</div> <div class="t-li1">
<span class="t-li">2)</span> <span class="t-mark-rev t-until-c23">(until C23)</span> Old-style (K&amp;R) function definition. This declaration does not introduce a prototype and any future <a href="operator_other#Function_call" title="c/language/operator other">function call expressions</a> will perform default argument promotions and will invoke undefined behavior if the number of arguments doesn't match the number of parameters. <div class="c source-c"><pre data-language="c">int max(a, b) 
    int a, b; // definition expects ints; the second call is undefined
{
    return a &gt; b ? a : b;
}
 
int n = max(true, (char)'a'); // calls max with two int args (after promotions)
 
int n = max(12.01f, 3.14); // calls max with two double args (after promotions)</pre></div>
</div> <div class="t-li1">
<span class="t-li">3)</span> <span class="t-rev-inl t-until-c23"><span>Non-prototype function declaration. This declaration does not introduce a prototype</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span>. <span class="t-rev-inl t-since-c23"><span>A new style function declaration equivalent to the <span class="t-spar">parameter-list</span> <code>void</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>.</div> <h3 id="Explanation"> Explanation</h3> <p>The return type of the function, determined by the type specifier in <span class="t-spar">specifiers-and-qualifiers</span> and possibly modified by the <span class="t-spar">declarator</span> as usual in <a href="declarations" title="c/language/declarations">declarations</a>, must be a non-array object type or the type <code>void</code>. If the function declaration is not a definition, the return type can be <a href="type#Incomplete_types" title="c/language/type">incomplete</a>. The return type cannot be cvr-qualified: any qualified return type is adjusted to its unqualified version for the purpose of constructing the function type.</p>
<div class="c source-c"><pre data-language="c">void f(char *s);                    // return type is void
int sum(int a, int b);              // return type of sum is int.
int (*foo(const void *p))[3];       // return type is pointer to array of 3 int
 
double const bar(void);             // declares function of type double(void)
double (*barp)(void) = bar;         // OK: barp is a pointer to double(void)
double const (*barpc)(void) = barp; // OK: barpc is also a pointer to double(void)</pre></div> <p>Function declarators can be combined with other declarators as long as they can share their type specifiers and qualifiers</p>
<div class="c source-c"><pre data-language="c">int f(void), *fip(), (*pfi)(), *ap[3]; // declares two functions and two objects
inline int g(int), n; // Error: inline qualifier is for functions only
typedef int array_t[3];
array_t a, h(); // Error: array type cannot be a return type for a function</pre></div> <p>If a function declaration appears outside of any function, the identifier it introduces has <a href="scope" title="c/language/scope">file scope</a> and <a href="storage_duration" title="c/language/storage duration">external linkage</a>, unless <code>static</code> is used or an earlier static declaration is visible. If the declaration occurs inside another function, the identifier has block scope (and also either internal or external linkage).</p>
<div class="c source-c"><pre data-language="c">int main(void)
{
    int f(int); // external linkage, block scope
    f(1); // definition needs to be available somewhere in the program
}</pre></div> <p>The parameters in a declaration<span class="t-rev-inl t-until-c23"><span> that is not part of a <a href="function_definition" title="c/language/function definition">function definition</a></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span> do not need to be named:</p>
<div class="c source-c"><pre data-language="c">int f(int, int); // declaration
// int f(int, int) { return 7; } // Error: parameters must be named in definitions
// This definition is allowed since C23</pre></div> <p>Each parameter in a <span class="t-spar">parameter-list</span> is a <a href="declarations" title="c/language/declarations">declaration</a> that introduced a single variable, with the following additional properties:</p>
<ul><li> the identifier in the declarator is optional <span class="t-rev-inl t-until-c23"><span>(except if this function declaration is part of a function definition)</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span> </li></ul> <div class="c source-c"><pre data-language="c">int f(int, double); // OK
int g(int a, double b); // also OK
// int f(int, double) { return 1; } // Error: definition must name parameters
// This definition is allowed since C23</pre></div> <ul><li> the only <a href="storage_duration" title="c/language/storage duration">storage class specifier</a> allowed for parameters is <code>register</code>, and it is ignored in function declarations that are not definitions </li></ul> <div class="c source-c"><pre data-language="c">int f(static int x); // Error
int f(int [static 10]); // OK (array index static is not a storage class specifier)</pre></div> <ul><li> any parameter of array type is adjusted to the corresponding pointer type<span class="t-rev-inl t-since-c99"><span>, which may be qualified if there are qualifiers between the square brackets of the array declarator</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> </li></ul> <div class="c source-c"><pre data-language="c">int f(int[]); // declares int f(int*)
int g(const int[10]); // declares int g(const int*)
int h(int[const volatile]); // declares int h(int * const volatile)
int x(int[*]); // declares int x(int*)</pre></div> <ul><li> any parameter of function type is adjusted to the corresponding pointer type </li></ul> <div class="c source-c"><pre data-language="c">int f(char g(double)); // declares int f(char (*g)(double))
int h(int(void)); // declares int h(int (*)(void))</pre></div> <ul><li> the parameter list may terminate with <code>, ...</code> <span class="t-rev-inl t-since-c23"><span>or be <code>...</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, see <a href="variadic" title="c/language/variadic">variadic functions</a> for details. </li></ul> <div class="c source-c"><pre data-language="c">int f(int, ...);</pre></div> <ul><li> parameters cannot have type <code>void</code> (but can have type pointer to void). The special parameter list that consists entirely of the keyword <code>void</code> is used to declare functions that take no parameters. </li></ul> <div class="c source-c"><pre data-language="c">int f(void); // OK
int g(void x); // Error</pre></div> <ul>
<li> any identifier that appears in a parameter list that could be treated as a typedef name or as a parameter name is treated as a typedef name: <code><span class="kw4">int</span> f<span class="br0">(</span><a href="http://en.cppreference.com/w/c/types/size_t"><span class="kw100">size_t</span></a>, <a href="http://en.cppreference.com/w/c/types/integer"><span class="kw133">uintptr_t</span></a><span class="br0">)</span></code> is parsed as a new-style declarator for a function taking two unnamed parameters of type size_t and uintptr_t, not an old-style declarator that begins the definition of a function taking two parameters named "size_t" and "uintptr_t" </li>
<li> parameters may have incomplete type<span class="t-rev-inl t-since-c99"><span> and may use the VLA notation [*]</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> (except that in a <a href="function_definition" title="c/language/function definition">function definition</a>, the parameter types after array-to-pointer and function-to-pointer adjustment must be complete) </li>
</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c23">
<td> <p><a href="attributes" title="c/language/attributes">Attribute specifier sequences</a> can also applied to function parameters.</p>
</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
</tr> </table> <p>See <a href="operator_other#Function_call" title="c/language/operator other">function call operator</a> for other details on the mechanics of a function call and <a href="return" title="c/language/return">return</a> for returning from functions.</p>
<h3 id="Notes"> Notes</h3> <table class="t-rev-begin"> <tr class="t-rev t-until-c23">
<td> <p>Unlike in C++, the declarators <code>f()</code> and <code>f(void)</code> have different meaning: the declarator <code>f(void)</code> is a new-style (prototype) declarator that declares a function that takes no parameters. The declarator <code>f()</code> is a declarator that declares a function that takes <i>unspecified</i> number of parameters (unless used in a function definition)</p>
<div class="c source-c"><pre data-language="c">int f(void); // declaration: takes no parameters
int g(); // declaration: takes unknown parameters
 
int main(void) {
    f(1); // compile-time error
    g(2); // undefined behavior
}
 
int f(void) { return 1; } // actual definition
int g(a,b,c,d) int a,b,c,d; { return 2; } // actual definition</pre></div> </td> <td><span class="t-mark-rev t-until-c23">(until C23)</span></td>
</tr> </table> <p>Unlike in a <a href="function_definition" title="c/language/function definition">function definition</a>, the parameter list may be inherited from a typedef</p>
<div class="c source-c"><pre data-language="c">typedef int p(int q, int r); // p is a function type int(int, int)
p f; // declares int f(int, int)</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-until-c99">
<td> <p>In C89, <span class="t-spar">specifiers-and-qualifiers</span> was optional, and if omitted, the return type of the function defaulted to <code>int</code> (possibly amended by the <span class="t-spar">declarator</span>).</p>
<div class="c source-c"><pre data-language="c">*f() { // function returning int*
   return NULL;
}</pre></div> </td> <td><span class="t-mark-rev t-until-c99">(until C99)</span></td>
</tr> </table> <h3 id="Defect_reports"> Defect reports</h3> <p>The following behavior-changing defect reports were applied retroactively to previously published C standards.</p>
<table class="dsctable"> <tr> <th>DR </th> <th>Applied to </th> <th>Behavior as published </th> <th>Correct behavior </th>
</tr> <tr> <td>
<a rel="nofollow" class="external text" href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2396.htm#dr_423">DR 423</a> </td> <td>C89 </td> <td>the return type might be qualified </td> <td>the return type is implicitly disqualified </td>
</tr>
</table> <h3 id="References"> References</h3>  <ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul><li> 6.7.6.3 Function declarators (including prototypes) (p: 96-98) </li></ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul><li> 6.7.6.3 Function declarators (including prototypes) (p: 133-136) </li></ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul><li> 6.7.5.3 Function declarators (including prototypes) (p: 118-121) </li></ul>
<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
<ul><li> 3.5.4.3 Function declarators (including prototypes) </li></ul>
</ul>            <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/function" title="cpp/language/function">C++ documentation</a></span> for <span class=""><span>Function declaration</span></span> </td>
</tr> </table>             <div class="_attribution">
  <p class="_attribution-p">
    &copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
    <a href="https://en.cppreference.com/w/c/language/function_declaration" class="_attribution-link">https://en.cppreference.com/w/c/language/function_declaration</a>
  </p>
</div>