diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Ffunction_definition.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Ffunction_definition.html')
| -rw-r--r-- | devdocs/c/language%2Ffunction_definition.html | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/devdocs/c/language%2Ffunction_definition.html b/devdocs/c/language%2Ffunction_definition.html new file mode 100644 index 00000000..8efefcc2 --- /dev/null +++ b/devdocs/c/language%2Ffunction_definition.html @@ -0,0 +1,93 @@ + <h1 id="firstHeading" class="firstHeading">Function definitions</h1> <p>A function definition associates the function body (a sequence of declarations and statements) with the function name and parameter list. Unlike <a href="function_declaration" title="c/language/function declaration">function declaration</a>, function definitions are allowed at file scope only (there are no nested functions).</p> +<p>C supports two different forms of function definitions:</p> +<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <span class="t-spar">attr-spec-seq</span><span class="t-mark">(optional)</span> <span class="t-spar">specifiers-and-qualifiers</span> <span class="t-spar">parameter-list-declarator</span> <span class="t-spar">function-body</span> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td> +</tr> <tr class="t-sdsc"> <td> <span class="t-spar">specifiers-and-qualifiers</span> <span class="t-spar">identifier-list-declarator</span> <span class="t-spar">declaration-list</span> <span class="t-spar">function-body</span> </td> <td> (2) </td> <td> <span class="t-mark-rev t-until-c23">(until C23)</span> </td> +</tr> +</table> <p>where</p> +<table class="t-par-begin"> <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 </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">specifiers-and-qualifiers</span> </td> <td> - </td> <td> a combination of <ul> +<li> <a href="declarations" title="c/language/declarations">type specifiers</a> that, possibly modified by the declarator, form the <i>return type</i> </li> +<li> <a href="storage_duration" title="c/language/storage duration">storage class specifiers</a>, which determine the linkage of the identifier (<code>static</code>, <code>extern</code>, or none) </li> +<li> function specifiers <a href="inline" title="c/language/inline"><code>inline</code></a>, <a href="_noreturn" title="c/language/ Noreturn"><code>_Noreturn</code></a>, or none </li> +</ul> </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">parameter-list-declarator</span> </td> <td> - </td> <td> a declarator for a function type which uses a <a href="function_declaration" title="c/language/function declaration">parameter list</a> to designate function parameters </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">identifier-list-declarator</span> </td> <td> - </td> <td> a declarator for a function type which uses a <a href="function_declaration" title="c/language/function declaration">identifier list</a> to designate function parameters </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">declaration-list</span> </td> <td> - </td> <td> sequence of declarations that declare every identifier in <span class="t-spar">identifier-list-declarator</span>. These declarations cannot use initializers and the only <a href="storage_duration" title="c/language/storage duration">storage-class specifier</a> allowed is <code>register</code>. </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">function-body</span> </td> <td> - </td> <td> a <a href="statements#Compound_statements" title="c/language/statements">compound statement</a>, that is a brace-enclosed sequence of declarations and statements, that is executed whenever this function is called </td> +</tr> +</table> <div class="t-li1"> +<span class="t-li">1)</span> New-style (C89) function definition. This definition both introduces the function itself and 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. <div class="c source-c"><pre data-language="c">int max(int a, int b) +{ + return a>b?a:b; +} + +double g(void) +{ + return 0.1; +}</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 definition does not behave as 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. <div class="c source-c"><pre data-language="c">int max(a, b) +int a, b; +{ + return a>b?a:b; +} +double g() +{ + return 0.1; +}</pre></div> +</div> <h3 id="Explanation"> Explanation</h3> <p>As with <a href="function_declaration" title="c/language/function declaration">function declarations</a>, 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 complete non-array object type or the type <code>void</code>. If the return type would be cvr-qualified, it 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) { 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])); +}</pre></div> <p>As with <a href="function_declaration" title="c/language/function declaration">function declarations</a>, 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 <a href="type#Compatible_types" title="c/language/type">compatible function type</a>.</p> +<table class="t-rev-begin"> <tr class="t-rev t-until-c23"> +<td> <p>Unlike <a href="function_declaration" title="c/language/function declaration">function declarations</a>, 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 <code>(void)</code>.</p> +</td> <td><span class="t-mark-rev t-until-c23">(until C23)</span></td> +</tr> <tr class="t-rev t-since-c23"> +<td> <p>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.</p> +</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <div class="c source-c"><pre data-language="c">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</pre></div> <p>Within the function body, every named parameter is an <a href="value_category" title="c/language/value category">lvalue</a> expression, they have automatic <a href="storage_duration" title="c/language/storage duration">storage duration</a> and <a href="scope" title="c/language/scope">block scope</a>. The layout of the parameters in memory (or if they are stored in memory at all) is unspecified: it is a part of the <a href="https://en.wikipedia.org/wiki/Calling_convention" class="extiw" title="enwiki:Calling convention">calling convention</a>.</p> +<div class="c source-c"><pre data-language="c">int main(int ac, char **av) +{ + ac = 2; // parameters are lvalues + av = (char *[]){"abc", "def", NULL}; + f(ac, av); +}</pre></div> <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> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <h3 id="func"> __func__</h3> <p>Within every <span class="t-spar">function-body</span>, the special predefined variable <code>__func__</code> with block scope and static storage duration is available, as if defined immediately after the opening brace by</p> +<div class="c source-c"><pre data-language="c">static const char __func__[] = "function name";</pre></div> <p>This special identifier is sometimes used in combination with the <a href="../preprocessor/replace" title="c/preprocessor/replace">predefined macro constants</a> <code>__FILE__</code> and <code>__LINE__</code>, for example, by <code><a href="../error/assert" title="c/error/assert">assert</a></code>.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Notes"> Notes</h3> <p>The argument list must be explicitly present in the declarator, it cannot 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 { return q + r; } // Error</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> +<p>In addition, old-style definition didn't require a declaration for every parameter in <span class="t-spar">declaration-list</span>. Any parameter whose declaration was missing had type <code>int</code></p> +<div class="c source-c"><pre data-language="c">max(a, b) // a and b have type int, return type is int +{ + return a>b?a:b; +}</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.9.1 Function definitions (p: 113-115) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.9.1 Function definitions (p: 156-158) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.9.1 Function definitions (p: 141-143) </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 3.7.1 Function definitions </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#Function_definition" title="cpp/language/function">C++ documentation</a></span> for <span class=""><span>Function definition</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_definition" class="_attribution-link">https://en.cppreference.com/w/c/language/function_definition</a> + </p> +</div> |
