summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Ftypedef.html
blob: 5deaefd39239198c9a358bd03d6a80b6c414c48b (plain)
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
    <h1 id="firstHeading" class="firstHeading">Typedef declaration</h1>            <p>The <i>typedef declaration</i> provides a way to declare an identifier as a type alias, to be used to replace a possibly complex <a href="type#Type_names" title="c/language/type">type name</a></p>
<p>The keyword <code>typedef</code> is used in a <a href="declarations" title="c/language/declarations">declaration</a>, in the grammatical position of a <a href="storage_duration" title="c/language/storage duration">storage-class specifier</a>, except that it does not affect storage or linkage:</p>
<div class="c source-c"><pre data-language="c">typedef int int_t; // declares int_t to be an alias for the type int
typedef char char_t, *char_p, (*fp)(void); // declares char_t to be an alias for char
                                           // char_p to be an alias for char*
                                           // fp to be an alias for char(*)(void)</pre></div>  <h3 id="Explanation"> Explanation</h3> <p>If a <a href="declarations" title="c/language/declarations">declaration</a> uses <code>typedef</code> as storage-class specifier, every declarator in it defines an identifier as an alias to the type specified. Since only one storage-class specifier is permitted in a declaration, typedef declaration cannot be <a href="storage_duration" title="c/language/storage duration">static or extern</a>.</p>
<p>typedef declaration does not introduce a distinct type, it only establishes a synonym for an existing type, thus typedef names are <a href="type#Compatible_types" title="c/language/type">compatible</a> with the types they alias. Typedef names share the <a href="name_space" title="c/language/name space">name space</a> with ordinary identifiers such as enumerators, variables and function.</p>
<table class="t-rev-begin"> <tr class="t-rev t-since-c99">
<td> <p>A typedef for a VLA can only appear at block scope. The length of the array is evaluated each time the flow of control passes over the typedef declaration, as opposed to the declaration of the array itself:</p>
<div class="c source-c"><pre data-language="c">void copyt(int n)
{
    typedef int B[n]; // B is a VLA, its size is n, evaluated now
    n += 1;
    B a; // size of a is n from before +=1
    int b[n]; // a and b are different sizes
    for (int i = 1; i &lt; n; i++)
        a[i-1] = b[i];
}</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td>
</tr> </table> <h3 id="Notes"> Notes</h3> <p>typedef name may be an <a href="type#Incomplete_types" title="c/language/type">incomplete type</a>, which may be completed as usual:</p>
<div class="c source-c"><pre data-language="c">typedef int A[]; // A is int[]
A a = {1, 2}, b = {3,4,5}; // type of a is int[2], type of b is int[3]</pre></div> <p>typedef declarations are often used to inject names from the tag <a href="name_space" title="c/language/name space">name space</a> into the ordinary name space:</p>
<div class="c source-c"><pre data-language="c">typedef struct tnode tnode; // tnode in ordinary name space
                            // is an alias to tnode in tag name space
struct tnode {
    int count;
    tnode *left, *right; // same as struct tnode *left, *right;
}; // now tnode is also a complete type
tnode s, *sp; // same as struct tnode s, *sp;</pre></div> <p>They can even avoid using the tag name space at all:</p>
<div class="c source-c"><pre data-language="c">typedef struct { double hi, lo; } range;
range z, *zp;</pre></div> <p>Typedef names are also commonly used to simplify the syntax of complex declarations:</p>
<div class="c source-c"><pre data-language="c">// array of 5 pointers to functions returning pointers to arrays of 3 ints
int (*(*callbacks[5])(void))[3]
 
// same with typedefs
typedef int arr_t[3]; // arr_t is array of 3 int
typedef arr_t* (*fp)(void); // pointer to function returning arr_t*
fp callbacks[5];</pre></div> <p>Libraries often expose system-dependent or configuration-dependent types as typedef names, to present a consistent interface to the users or to other library components:</p>
<div class="c source-c"><pre data-language="c">#if defined(_LP64)
typedef int     wchar_t;
#else
typedef long    wchar_t;
#endif</pre></div> <h3 id="References"> References</h3>  <ul>
<li> C23 standard (ISO/IEC 9899:2023): </li>
<ul><li> 6.7.8 Type definitions (p: TBD) </li></ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul><li> 6.7.8 Type definitions (p: TBD) </li></ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul><li> 6.7.8 Type definitions (p: 137-138) </li></ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul><li> 6.7.7 Type definitions (p: 123-124) </li></ul>
<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
<ul><li> 3.5.6 Type definitions </li></ul>
</ul>                   <h3 id="Keywords"> Keywords</h3> <p><a href="../keyword/typedef" title="c/keyword/typedef"><code>typedef</code></a></p>
<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/typedef" title="cpp/language/typedef">C++ documentation</a></span> for <span class=""><span><code>typedef</code> declaration</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/typedef" class="_attribution-link">https://en.cppreference.com/w/c/language/typedef</a>
  </p>
</div>