1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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>
|