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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
<h1 id="firstHeading" class="firstHeading">Compound literals <span class="t-mark-rev t-since-c99">(since C99)</span>
</h1> <p>Constructs an unnamed object of specified type (which may be struct, union, or even array type) in-place.</p>
<h3 id="Syntax"> Syntax</h3> <table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>(</code> <span class="t-spar">storage-class-specifiers</span> <span class="t-mark">(optional)</span><span class="t-mark-rev t-since-c23">(since C23)</span> <span class="t-spar">type</span> <code>)</code> <code>{</code> <span class="t-spar">initializer-list</span> <code>}</code> </td> <td class="t-sdsc-nopad"> </td> <td> <span class="t-mark-rev t-since-c99">(since C99)</span> </td>
</tr> <tr class="t-sdsc"> <td> <code>(</code> <span class="t-spar">storage-class-specifiers</span> <span class="t-mark">(optional)</span><span class="t-mark-rev t-since-c23">(since C23)</span> <span class="t-spar">type</span> <code>)</code> <code>{</code> <span class="t-spar">initializer-list</span> <code>,</code> <code>}</code> </td> <td class="t-sdsc-nopad"> </td> <td> <span class="t-mark-rev t-since-c99">(since C99)</span> </td>
</tr> <tr class="t-sdsc"> <td> <code>(</code> <span class="t-spar">storage-class-specifiers</span> <span class="t-mark">(optional)</span> <span class="t-spar">type</span> <code>)</code> <code>{</code> <code>}</code> </td> <td class="t-sdsc-nopad"> </td> <td> <span class="t-mark-rev t-since-c23">(since C23)</span> </td>
</tr>
</table> <p>where</p>
<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">storage-class-specifiers</span> </td> <td> - </td> <td> <span class="t-mark-rev t-since-c23">(since C23)</span> A list of <a href="storage_duration" title="c/language/storage duration">storage class specifiers</a> that can contain only <code>constexpr</code>, <code>static</code>, <code>register</code>, or <code><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></code> </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">type</span> </td> <td> - </td> <td> a <a href="type#Type_names" title="c/language/type">type name</a> specifying any complete object type or an array of unknown size, but not a VLA </td>
</tr> <tr class="t-par"> <td> <span class="t-spar">initializer-list</span> </td> <td> - </td> <td> list of initializers suitable for <a href="initialization" title="c/language/initialization">initialization</a> of an object of <span class="t-spar">type</span> </td>
</tr>
</table> <h3 id="Explanation"> Explanation</h3> <p>The compound literal expression constructs an unnamed object of the type specified by <span class="t-spar">type</span> and initializes it as specified by <span class="t-spar">initializer-list</span>. <a href="initialization" title="c/language/initialization">Designated initializers</a> are accepted.</p>
<p>The type of the compound literal is <span class="t-spar">type</span> (except when <span class="t-spar">type</span> is an array of unknown size; its size is deduced from the <span class="t-spar">initializer-list</span> as in <a href="array_initialization" title="c/language/array initialization">array initialization</a>).</p>
<p>The value category of a compound literal is <a href="value_category" title="c/language/value category">lvalue</a> (its address can be taken).</p>
<table class="t-rev-begin"> <tr class="t-rev t-until-c23">
<td>The unnamed object to which the compound literal evaluates has static <a href="storage_duration" title="c/language/storage duration">storage duration</a> if the compound literal occurs at file scope and automatic <a href="storage_duration" title="c/language/storage duration">storage duration</a> if the compound literal occurs at block scope (in which case the object's <a href="lifetime" title="c/language/lifetime">lifetime</a> ends at the end of the enclosing block).</td> <td><span class="t-mark-rev t-until-c23">(until C23)</span></td>
</tr> <tr class="t-rev t-since-c23">
<td>If the compound literal is evaluated outside the body of a function and outside of any parameter list, it is associated with file scope; otherwise, it is associated with the enclosing block. Depending on this association, the storage-class specifiers (possibly empty), type name, and initializer list, if any, shall be such that they are valid specifiers for an object definition in file scope or block scope, respectively, of the following form, <pre data-language="c"> storage-class-specifiers typeof(type) ID = { initializer-list };
</pre> where ID is an identifier that is unique for the whole program. A compound literal provides an unnamed object whose value, type, storage duration and other properties are as if given by the definition syntax above; if the storage duration is automatic, the lifetime of the instance of the unnamed object is the current execution of the enclosing block. If the storage-class specifiers contain other specifiers than <code>constexpr</code>, <code>static</code>, <code>register</code>, or <code><a href="http://en.cppreference.com/w/c/thread/thread_local"><span class="kw1032">thread_local</span></a></code> the behavior is undefined.</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td>
</tr> </table> <h3 id="Notes"> Notes</h3> <p>Compound literals of const-qualified character or wide character array types may share storage with <a href="string_literal" title="c/language/string literal">string literals</a>.</p>
<div class="c source-c"><pre data-language="c">(const char []){"abc"} == "abc" // might be 1 or 0, unspecified</pre></div> <p>Each compound literal creates only a single object in its scope:</p>
<div class="c source-c"><pre data-language="c">int f (void)
{
struct s {int i;} *p = 0, *q;
int j = 0;
again:
q = p, p = &((struct s){ j++ });
if (j < 2) goto again; // note; if a loop were used, it would end scope here,
// which would terminate the lifetime of the compound literal
// leaving p as a dangling pointer
return p == q && q->i == 1; // always returns 1
}</pre></div> <p>Because compound literals are unnamed, a compound literal cannot reference itself (a named struct can include a pointer to itself)</p>
<p>Although the syntax of a compound literal is similar to a <a href="cast" title="c/language/cast">cast</a>, the important distinction is that a cast is a non-lvalue expression while a compound literal is an lvalue.</p>
<h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h>
int *p = (int[]){2, 4}; // creates an unnamed static array of type int[2]
// initializes the array to the values {2, 4}
// creates pointer p to point at the first element of
// the array
const float *pc = (const float []){1e0, 1e1, 1e2}; // read-only compound literal
struct point {double x,y;};
int main(void)
{
int n = 2, *p = &n;
p = (int [2]){*p}; // creates an unnamed automatic array of type int[2]
// initializes the first element to the value formerly
// held in *p
// initializes the second element to zero
// stores the address of the first element in p
void drawline1(struct point from, struct point to);
void drawline2(struct point *from, struct point *to);
drawline1(
(struct point){.x=1, .y=1}, // creates two structs with block scope and
(struct point){.x=3, .y=4}); // calls drawline1, passing them by value
drawline2(
&(struct point){.x=1, .y=1}, // creates two structs with block scope and
&(struct point){.x=3, .y=4}); // calls drawline2, passing their addresses
}
void drawline1(struct point from, struct point to)
{
printf("drawline1: `from` @ %p {%.2f, %.2f}, `to` @ %p {%.2f, %.2f}\n",
(void*)&from, from.x, from.y, (void*)&to, to.x, to.y);
}
void drawline2(struct point *from, struct point *to)
{
printf("drawline2: `from` @ %p {%.2f, %.2f}, `to` @ %p {%.2f, %.2f}\n",
(void*)from, from->x, from->y, (void*)to, to->x, to->y);
}</pre></div> <p>Possible output:</p>
<div class="text source-text"><pre data-language="c">drawline1: `from` @ 0x7ffd24facea0 {1.00, 1.00}, `to` @ 0x7ffd24face90 {3.00, 4.00}
drawline2: `from` @ 0x7ffd24facec0 {1.00, 1.00}, `to` @ 0x7ffd24faced0 {3.00, 4.00}</pre></div> </div> <h3 id="References"> References</h3> <ul>
<li> C23 standard (ISO/IEC 9899:2023): </li>
<ul><li> 6.5.2.5 Compound literals (p: TBD) </li></ul>
<li> C17 standard (ISO/IEC 9899:2018): </li>
<ul><li> 6.5.2.5 Compound literals (p: 61-63) </li></ul>
<li> C11 standard (ISO/IEC 9899:2011): </li>
<ul><li> 6.5.2.5 Compound literals (p: 85-87) </li></ul>
<li> C99 standard (ISO/IEC 9899:1999): </li>
<ul><li> 6.5.2.5 Compound literals (p: 75-77) </li></ul>
</ul> <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/compound_literal" class="_attribution-link">https://en.cppreference.com/w/c/language/compound_literal</a>
</p>
</div>
|