Designated initializers for aggregate types (C only)
Designated initializers, a C99 feature, are supported for aggregate types, including arrays, structures, and unions. A designated initializer, or designator, points out a particular element to be initialized. A designator list is a comma-separated list of one or more designators. A designator list followed by an equal sign constitutes a designation.
Designated initializers allow for the following flexibility:
- Elements within an aggregate can be initialized in any order.
- The initializer list can omit elements that are declared anywhere in the aggregate, rather than only at the end. Elements that are omitted are initialized as if they are static objects: arithmetic types are initialized to 0; pointers are initialized to NULL.
- Where inconsistent or incomplete bracketing of initializers for multi-dimensional arrays or nested aggregates may be difficult to understand, designators can more clearly identify the element or member to be initialized.
In the following example, the designator is
.any_member
and
the designated initializer is .any_member = 13
: union { /* … */ } caw = { .any_member = 13 };
The following example shows how the second and third members
b
and c
of
structure variable klm
are initialized with designated
initializers: struct xyz {
int a;
int b;
int c;
} klm = { .a = 99, .c = 100 };
In the following example, the third and second elements
of the one-dimensional array
aa
are initialized to 3
and 6
,
respectively: int aa[4] = { [2] = 3, [1] = 6 };
The following example initializes the first four and last
four elements, while omitting the middle four:
static short grid[3] [4] = { [0][0]=8, [0][1]=6,
[0][2]=4, [0][3]=1,
[2][0]=9, [2][1]=3,
[2][2]=1, [2][3]=1 };
The
omitted four elements of grid
are initialized to
zero: Element | Value | Element | Value |
---|---|---|---|
grid[0] [0] |
8 | grid[1] [2] |
0 |
grid[0] [1] |
6 | grid[1] [3] |
0 |
grid[0] [2] |
4 | grid[2] [0] |
9 |
grid[0] [3] |
1 | grid[2] [1] |
3 |
grid[1] [0] |
0 | grid[2] [2] |
1 |
grid[1] [1] |
0 | grid[2] [3] |
1 |
Designated initializers can be combined with regular initializers,
as in the following example:
int a[10] = {2, 4, [8]=9, 10}
In
this example, a[0]
is initialized to 2
, a[1]
is
initialized to 4
, a[2]
to a[7]
are
initialized to 0, and a[9]
is initialized to 10
.In the following example, a single designator is used
to "allocate" space from both ends of an array:
int a[MAX] = {
1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
};
The designated initializer, [MAX-5] = 8
,
means that the array element at subscript MAX-5
should
be initialized to the value 8
. If MAX
is 15
, a[5]
through a[9]
will
be initialized to zero. If MAX
is 7
, a[2]
through a[4]
will
first have the values 5
, 7
, and 9
,
respectively, which are overridden by the values 8
, 6
,
and 4
. In other words, if MAX
is
7, the initialization would be the same as if the declaration had
been written: int a[MAX] = {
1, 3, 8, 6, 4, 2, 0
};
You can also use designators to represent members of nested
structures. For example:
struct a {
struct b {
int c;
int d;
} e;
float f;
} g = {.e.c = 3 };
initializes member c
of structure variable e
,
which is a member of structure variable g
, to the
value of 3.