summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Ffunction_definition.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /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.html93
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&gt;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&amp;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&gt;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&amp;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&amp;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&gt;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">
+ &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_definition" class="_attribution-link">https://en.cppreference.com/w/c/language/function_definition</a>
+ </p>
+</div>