summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Fgeneric.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%2Fgeneric.html
new repository
Diffstat (limited to 'devdocs/c/language%2Fgeneric.html')
-rw-r--r--devdocs/c/language%2Fgeneric.html62
1 files changed, 62 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fgeneric.html b/devdocs/c/language%2Fgeneric.html
new file mode 100644
index 00000000..670853f3
--- /dev/null
+++ b/devdocs/c/language%2Fgeneric.html
@@ -0,0 +1,62 @@
+ <h1 id="firstHeading" class="firstHeading">Generic selection <span class="t-mark-rev t-since-c11">(since C11)</span>
+</h1> <p>Provides a way to choose one of several expressions at compile time, based on a type of a controlling expression</p>
+<h3 id="Syntax"> Syntax</h3> <table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>_Generic</code> <code>(</code> <span class="t-spar">controlling-expression</span> <code>,</code> <span class="t-spar">association-list</span> <code>)</code> </td> <td class="t-sdsc-nopad"> </td> <td> <span class="t-mark-rev t-since-c11">(since C11)</span> </td>
+</tr>
+</table> <p>where <span class="t-spar">association-list</span> is a comma-separated list of associations, each of which has the syntax</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">type-name</span> <code>:</code> <span class="t-spar">expression</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
+</tr> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <code>default</code> <code>:</code> <span class="t-spar">expression</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">type-name</span> </td> <td> - </td> <td> any complete <a href="type" title="c/language/type">object type</a> that isn't variably-modified (that is, not VLA or pointer to VLA). </td>
+</tr> <tr class="t-par"> <td> <span class="t-spar">controlling-expression</span> </td> <td> - </td> <td> any expression (except for the <a href="operator_other#Comma_operator" title="c/language/operator other">comma operator</a>) whose type must be compatible with one of the <span class="t-spar">type-name</span>s if the <code>default</code> association is not used </td>
+</tr> <tr class="t-par"> <td> <span class="t-spar">expression</span> </td> <td> - </td> <td> any expression (except for the <a href="operator_other#Comma_operator" title="c/language/operator other">comma operator</a>) of any type and value category </td>
+</tr>
+</table> <p>No two <span class="t-spar">type-name</span>s in the <span class="t-spar">association-list</span> may specify <a href="type#Compatible_types" title="c/language/type">compatible types</a>. There may be only one association that uses the keyword <code>default</code>. If <code>default</code> is not used and none of the <span class="t-spar">type-name</span>s are compatible with the type of the controlling expression, the program will not compile.</p>
+<h3 id="Explanation"> Explanation</h3> <p>First, the type of <span class="t-spar">controlling-expression</span> undergoes <a href="conversion#Lvalue_conversions" title="c/language/conversion">lvalue conversions</a>. The conversion is performed in type domain only: it discards the top-level cvr-qualifiers and atomicity and applies array-to-pointer/function-to-pointer transformations to the type of the controlling expression, without initiating any side-effects or calculating any values.</p>
+<p>The type after conversion is compared with <span class="t-spar">type-name</span>s from the list of associations.</p>
+<p>If the type is <a href="type#Compatible_types" title="c/language/type">compatible</a> with the <span class="t-spar">type-name</span> of one of the associations, then the type, value, and <a href="value_category" title="c/language/value category">value category</a> of the generic selection are the type, value, and value category of the <span class="t-spar">expression</span> that appears after the colon for that <span class="t-spar">type-name</span>.</p>
+<p>If none of the <span class="t-spar">type-name</span>s are compatible with the type of the <span class="t-spar">controlling-expression</span>, and the <code>default</code> association is provided, then the type, value, and value category of the generic selection are the type, value, and value category of the expression after the <code>defaultĀ :</code> label.</p>
+<h3 id="Notes"> Notes</h3> <p>The <span class="t-spar">controlling-expression</span> and the <span class="t-spar">expression</span>s of the selections that are not chosen are never evaluated.</p>
+<p>Because of the lvalue conversions, <code>"abc"</code> matches <code>char*</code> and not <code>char[4]</code> and <code>(int const){0}</code> matches <code>int</code>, and not <code>const int</code>.</p>
+<p>All <a href="value_category" title="c/language/value category">value categories</a>, including function designators and void expressions, are allowed as <span class="t-spar">expression</span>s in a generic selection, and if selected, the generic selection itself has the same value category.</p>
+<p>The <a href="../numeric/tgmath" title="c/numeric/tgmath">type-generic math macros</a> from <a href="../numeric/tgmath" title="c/numeric/tgmath"><code>&lt;tgmath.h&gt;</code></a>, introduced in C99, were implemented in compiler-specific manner. Generic selections, introduced in C11, gave the programmers the ability to write similar type-dependent code.</p>
+<p>Generic selection is similar to overloading in C++ (where one of several functions is chosen at compile time based on the types of the arguments), except that it makes the selection between arbitrary expressions.</p>
+<h3 id="Keywords"> Keywords</h3> <p><a href="../keyword/_generic" title="c/keyword/ Generic"><code>_Generic</code></a>, <a href="../keyword/default" title="c/keyword/default"><code>default</code></a></p>
+<h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+// Possible implementation of the tgmath.h macro cbrt
+#define cbrt(X) _Generic((X), \
+ long double: cbrtl, \
+ default: cbrt, \
+ float: cbrtf \
+ )(X)
+
+int main(void)
+{
+ double x = 8.0;
+ const float y = 3.375;
+ printf("cbrt(8.0) = %f\n", cbrt(x)); // selects the default cbrt
+ printf("cbrtf(3.375) = %f\n", cbrt(y)); // converts const float to float,
+ // then selects cbrtf
+}</pre></div> <p>Output:</p>
+<div class="text source-text"><pre data-language="c">cbrt(8.0) = 2.000000
+cbrtf(3.375) = 1.500000</pre></div> </div> <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_481">DR 481</a> </td> <td>C11 </td> <td>it was underspecified if the controlling expression undergoes lvalue conversions </td> <td>it undergoes </td>
+</tr>
+</table> <h3 id="References"> References</h3> <ul>
+<li> C23 standard (ISO/IEC 9899:2023): </li>
+<ul><li> 6.5.1.1 Generic selection (p: TBD) </li></ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul><li> 6.5.1.1 Generic selection (p: 56-57) </li></ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul><li> 6.5.1.1 Generic selection (p: 78-79) </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/templates" title="cpp/language/templates">C++ documentation</a></span> for <span class=""><span>Templates</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/generic" class="_attribution-link">https://en.cppreference.com/w/c/language/generic</a>
+ </p>
+</div>