diff options
Diffstat (limited to 'devdocs/c/language%2Finline.html')
| -rw-r--r-- | devdocs/c/language%2Finline.html | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/devdocs/c/language%2Finline.html b/devdocs/c/language%2Finline.html new file mode 100644 index 00000000..b5413a96 --- /dev/null +++ b/devdocs/c/language%2Finline.html @@ -0,0 +1,77 @@ + <h1 id="firstHeading" class="firstHeading">inline function specifier</h1> <p>Declares an <a href="https://en.wikipedia.org/wiki/inline_function" class="extiw" title="enwiki:inline function">inline function</a>.</p> +<h3 id="Syntax"> Syntax</h3> <table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>inline</code> <span class="t-spar">function_declaration</span> </td> <td class="t-sdsc-nopad"> </td> <td> <span class="t-mark-rev t-since-c99">(since C99)</span> </td> +</tr> +</table> <h3 id="Explanation"> Explanation</h3> <p>The intent of the <code>inline</code> specifier is to serve as a hint for the compiler to perform optimizations, such as <a href="https://en.wikipedia.org/wiki/inline_expansion" class="extiw" title="enwiki:inline expansion">function inlining</a>, which usually require the definition of a function to be visible at the call site. The compilers can (and usually do) ignore presence or absence of the <code>inline</code> specifier for the purpose of optimization.</p> +<p>If the compiler performs function inlining, it replaces a call of that function with its body, avoiding the overhead of a function call (placing data on stack and retrieving the result), which may result in a larger executable as the code for the function has to be repeated multiple times. The result is similar to <a href="../preprocessor/replace" title="c/preprocessor/replace">function-like macros</a>, except that identifiers and macros used in the function refer to the definitions visible at the point of definition, not at the point of call.</p> +<p>Regardless of whether inlining takes place, the following semantics of inline functions are guaranteed:</p> +<p>Any function with internal linkage may be declared <code>static inline</code> with no other restrictions.</p> +<p>A non-static inline function cannot define a non-const function-local static and cannot refer to a file-scope static.</p> +<div class="c source-c"><pre data-language="c">static int x; + +inline void f(void) +{ + static int n = 1; // error: non-const static in a non-static inline function + int k = x; // error: non-static inline function accesses a static variable +}</pre></div> <p>If a non-static function is declared <code>inline</code>, then it must be defined in the same translation unit. The inline definition that does not use <code>extern</code> is not externally visible and does not prevent other translation units from defining the same function. This makes the <code>inline</code> keyword an alternative to <code>static</code> for defining functions inside header files, which may be included in multiple translation units of the same program.</p> +<p>If a function is declared <code>inline</code> in some translation units, it does not need to be declared <code>inline</code> everywhere: at most one translation unit may also provide a regular, non-inline non-static function, or a function declared <code>extern inline</code>. This one translation unit is said to provide the <i>external definition</i>. In order to avoid undefined behavior, one external definition must exist in the program if the name of the function with external linkage is used in an expression, see <a href="extern#One_definition_rule" title="c/language/extern">one definition rule</a>.</p> +<p>The address of an inline function with external linkage is always the address of the external definition, but when this address is used to make a function call, it's unspecified whether the <i>inline definition</i> (if present in the translation unit) or the <i>external definition</i> is called. The static objects defined within an inline definition are distinct from the static objects defined within the external definition:</p> +<div class="c source-c"><pre data-language="c">inline const char *saddr(void) // the inline definition for use in this file +{ + static const char name[] = "saddr"; + return name; +} + +int compare_name(void) +{ + return saddr() == saddr(); // unspecified behavior, one call could be external +} + +extern const char *saddr(void); // an external definition is generated, too</pre></div> <p>A C program should not depend on whether the inline version or the external version of a function is called, otherwise the behavior is unspecified.</p> +<h3 id="Keywords"> Keywords</h3> <p><a href="../keyword/inline" title="c/keyword/inline"><code>inline</code></a></p> +<h3 id="Notes"> Notes</h3> <p>The <code>inline</code> keyword was adopted from C++, but in C++, if a function is declared <code>inline</code>, it must be declared <code>inline</code> in every translation unit, and also every definition of an inline function must be exactly the same (in C, the definitions may be different, and depending on the differences only results in unspecified behavior). On the other hand, C++ allows non-const function-local statics and all function-local statics from different definitions of an inline function are the same in C++ but distinct in C.</p> +<h3 id="Example"> Example</h3> <table class="t-rev-begin"> <tr class="t-rev"> +<td> <p>Header file "test.h"</p> +<div class="c source-c"><pre data-language="c">#ifndef TEST_H_INCLUDED +#define TEST_H_INCLUDED + +inline int sum(int a, int b) +{ + return a + b; +} + +#endif</pre></div> <p>Source file "sum.c"</p> +<div class="c source-c"><pre data-language="c">#include "test.h" + +extern inline int sum(int a, int b); // provides external definition</pre></div> <p>Source file "test1.c"</p> +<div class="c source-c"><pre data-language="c">#include <stdio.h> +#include "test.h" + +extern int f(void); + +int main(void) +{ + printf("%d\n", sum(1, 2) + f()); +}</pre></div> <p>Source file "test2.c"</p> +<div class="c source-c"><pre data-language="c">#include "test.h" + +int f(void) +{ + return sum(3, 4); +}</pre></div> <p>Output</p> +<div class="c source-c"><pre data-language="c">10</pre></div> </td> <td></td> +</tr> </table> <h3 id="References"> References</h3> <ul> +<li> C23 standard (ISO/IEC 9899:2023): </li> +<ul><li> 6.7.4 Function specifiers (p: TBD) </li></ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.7.4 Function specifiers (p: TBD) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.7.4 Function specifiers (p: 125-127) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.7.4 Function specifiers (p: 112-113) </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/inline" title="cpp/language/inline">C++ documentation</a></span> for <span class=""><span><code>inline</code> specifier</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/inline" class="_attribution-link">https://en.cppreference.com/w/c/language/inline</a> + </p> +</div> |
