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/gcc~13/nested-functions.html | |
new repository
Diffstat (limited to 'devdocs/gcc~13/nested-functions.html')
| -rw-r--r-- | devdocs/gcc~13/nested-functions.html | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/devdocs/gcc~13/nested-functions.html b/devdocs/gcc~13/nested-functions.html new file mode 100644 index 00000000..e3336969 --- /dev/null +++ b/devdocs/gcc~13/nested-functions.html @@ -0,0 +1,62 @@ +<div class="section-level-extent" id="Nested-Functions"> <div class="nav-panel"> <p> Next: <a href="nonlocal-gotos" accesskey="n" rel="next">Nonlocal Gotos</a>, Previous: <a href="labels-as-values" accesskey="p" rel="prev">Labels as Values</a>, Up: <a href="c-extensions" accesskey="u" rel="up">Extensions to the C Language Family</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div> <h1 class="section" id="Nested-Functions-1"><span>6.4 Nested Functions<a class="copiable-link" href="#Nested-Functions-1"> ¶</a></span></h1> <p>A <em class="dfn">nested function</em> is a function defined inside another function. Nested functions are supported as an extension in GNU C, but are not supported by GNU C++. </p> <p>The nested function’s name is local to the block where it is defined. For example, here we define a nested function named <code class="code">square</code>, and call it twice: </p> <div class="example smallexample"> <div class="group"><pre class="example-preformatted" data-language="cpp">foo (double a, double b) +{ + double square (double z) { return z * z; } + + return square (a) + square (b); +}</pre></div> +</div> <p>The nested function can access all the variables of the containing function that are visible at the point of its definition. This is called <em class="dfn">lexical scoping</em>. For example, here we show a nested function which uses an inherited variable named <code class="code">offset</code>: </p> <div class="example smallexample"> <div class="group"><pre class="example-preformatted" data-language="cpp">bar (int *array, int offset, int size) +{ + int access (int *array, int index) + { return array[index + offset]; } + int i; + /* <span class="r">…</span> */ + for (i = 0; i < size; i++) + /* <span class="r">…</span> */ access (array, i) /* <span class="r">…</span> */ +}</pre></div> +</div> <p>Nested function definitions are permitted within functions in the places where variable definitions are allowed; that is, in any block, mixed with the other declarations and statements in the block. </p> <p>It is possible to call the nested function from outside the scope of its name by storing its address or passing the address to another function: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">hack (int *array, int size) +{ + void store (int index, int value) + { array[index] = value; } + + intermediate (store, size); +}</pre> +</div> <p>Here, the function <code class="code">intermediate</code> receives the address of <code class="code">store</code> as an argument. If <code class="code">intermediate</code> calls <code class="code">store</code>, the arguments given to <code class="code">store</code> are used to store into <code class="code">array</code>. But this technique works only so long as the containing function (<code class="code">hack</code>, in this example) does not exit. </p> <p>If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it’s not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe. </p> <p>GCC implements taking the address of a nested function using a technique called <em class="dfn">trampolines</em>. This technique was described in Lexical Closures for C++ (Thomas M. Breuel, USENIX C++ Conference Proceedings, October 17-21, 1988). </p> <p>A nested function can jump to a label inherited from a containing function, provided the label is explicitly declared in the containing function (see <a class="pxref" href="local-labels">Locally Declared Labels</a>). Such a jump returns instantly to the containing function, exiting the nested function that did the <code class="code">goto</code> and any intermediate functions as well. Here is an example: </p> <div class="example smallexample"> <div class="group"><pre class="example-preformatted" data-language="cpp">bar (int *array, int offset, int size) +{ + __label__ failure; + int access (int *array, int index) + { + if (index > size) + goto failure; + return array[index + offset]; + } + int i; + /* <span class="r">…</span> */ + for (i = 0; i < size; i++) + /* <span class="r">…</span> */ access (array, i) /* <span class="r">…</span> */ + /* <span class="r">…</span> */ + return 0; + + /* <span class="r">Control comes here from <code class="code">access</code> + if it detects an error.</span> */ + failure: + return -1; +}</pre></div> +</div> <p>A nested function always has no linkage. Declaring one with <code class="code">extern</code> or <code class="code">static</code> is erroneous. If you need to declare the nested function before its definition, use <code class="code">auto</code> (which is otherwise meaningless for function declarations). </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">bar (int *array, int offset, int size) +{ + __label__ failure; + auto int access (int *, int); + /* <span class="r">…</span> */ + int access (int *array, int index) + { + if (index > size) + goto failure; + return array[index + offset]; + } + /* <span class="r">…</span> */ +}</pre> +</div> </div> <div class="nav-panel"> <p> Next: <a href="nonlocal-gotos">Nonlocal Gotos</a>, Previous: <a href="labels-as-values">Labels as Values</a>, Up: <a href="c-extensions">Extensions to the C Language Family</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div><div class="_attribution"> + <p class="_attribution-p"> + © Free Software Foundation<br>Licensed under the GNU Free Documentation License, Version 1.3.<br> + <a href="https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Nested-Functions.html" class="_attribution-link">https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Nested-Functions.html</a> + </p> +</div> |
