summaryrefslogtreecommitdiff
path: root/devdocs/gcc~13/labels-as-values.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/gcc~13/labels-as-values.html
new repository
Diffstat (limited to 'devdocs/gcc~13/labels-as-values.html')
-rw-r--r--devdocs/gcc~13/labels-as-values.html15
1 files changed, 15 insertions, 0 deletions
diff --git a/devdocs/gcc~13/labels-as-values.html b/devdocs/gcc~13/labels-as-values.html
new file mode 100644
index 00000000..47422c16
--- /dev/null
+++ b/devdocs/gcc~13/labels-as-values.html
@@ -0,0 +1,15 @@
+<div class="section-level-extent" id="Labels-as-Values"> <div class="nav-panel"> <p> Next: <a href="nested-functions" accesskey="n" rel="next">Nested Functions</a>, Previous: <a href="local-labels" accesskey="p" rel="prev">Locally Declared Labels</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="Labels-as-Values-1"><span>6.3 Labels as Values<a class="copiable-link" href="#Labels-as-Values-1"> ¶</a></span></h1> <p>You can get the address of a label defined in the current function (or a containing function) with the unary operator ‘<samp class="samp">&amp;&amp;</samp>’. The value has type <code class="code">void *</code>. This value is a constant and can be used wherever a constant of that type is valid. For example: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">void *ptr;
+/* <span class="r">…</span> */
+ptr = &amp;&amp;foo;</pre>
+</div> <p>To use these values, you need to be able to jump to one. This is done with the computed goto statement<a class="footnote" id="DOCF6" href="#FOOT6"><sup>6</sup></a>, <code class="code">goto *<var class="var">exp</var>;</code>. For example, </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">goto *ptr;</pre>
+</div> <p>Any expression of type <code class="code">void *</code> is allowed. </p> <p>One way of using these constants is in initializing a static array that serves as a jump table: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">static void *array[] = { &amp;&amp;foo, &amp;&amp;bar, &amp;&amp;hack };</pre>
+</div> <p>Then you can select a label with indexing, like this: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">goto *array[i];</pre>
+</div> <p>Note that this does not check whether the subscript is in bounds—array indexing in C never does that. </p> <p>Such an array of label values serves a purpose much like that of the <code class="code">switch</code> statement. The <code class="code">switch</code> statement is cleaner, so use that rather than an array unless the problem does not fit a <code class="code">switch</code> statement very well. </p> <p>Another use of label values is in an interpreter for threaded code. The labels within the interpreter function can be stored in the threaded code for super-fast dispatching. </p> <p>You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things happen. The best way to avoid this is to store the label address only in automatic variables and never pass it as an argument. </p> <p>An alternate way to write the above example is </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">static const int array[] = { &amp;&amp;foo - &amp;&amp;foo, &amp;&amp;bar - &amp;&amp;foo,
+ &amp;&amp;hack - &amp;&amp;foo };
+goto *(&amp;&amp;foo + array[i]);</pre>
+</div> <p>This is more friendly to code living in shared libraries, as it reduces the number of dynamic relocations that are needed, and by consequence, allows the data to be read-only. This alternative with label differences is not supported for the AVR target, please use the first approach for AVR programs. </p> <p>The <code class="code">&amp;&amp;foo</code> expressions for the same label might have different values if the containing function is inlined or cloned. If a program relies on them being always the same, <code class="code">__attribute__((__noinline__,__noclone__))</code> should be used to prevent inlining and cloning. If <code class="code">&amp;&amp;foo</code> is used in a static variable initializer, inlining and cloning is forbidden. </p> </div> <div class="footnotes-segment"> <h2 class="footnotes-heading">Footnotes</h2> <h3 class="footnote-body-heading"><a id="FOOT6" href="#DOCF6">(6)</a></h3> <p>The analogous feature in Fortran is called an assigned goto, but that name seems inappropriate in C, where one can do more than simply store label addresses in label variables.</p> </div> <div class="nav-panel"> <p> Next: <a href="nested-functions">Nested Functions</a>, Previous: <a href="local-labels">Locally Declared Labels</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">
+ &copy; 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/Labels-as-Values.html" class="_attribution-link">https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Labels-as-Values.html</a>
+ </p>
+</div>