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/c/language%2Fgeneric.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Fgeneric.html')
| -rw-r--r-- | devdocs/c/language%2Fgeneric.html | 62 |
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><tgmath.h></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 <math.h> +#include <stdio.h> + +// 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"> + © 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> |
