diff options
Diffstat (limited to 'devdocs/c/language%2Ffunction_declaration.html')
| -rw-r--r-- | devdocs/c/language%2Ffunction_declaration.html | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/devdocs/c/language%2Ffunction_declaration.html b/devdocs/c/language%2Ffunction_declaration.html new file mode 100644 index 00000000..af2619d7 --- /dev/null +++ b/devdocs/c/language%2Ffunction_declaration.html @@ -0,0 +1,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&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 > 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"> + © 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> |
