Initialization
Because of the language's grammar, a scalar initializer may be enclosed in any number of curly brace pairs. Most compilers issue a warning if there is more than one such pair, though.
int x = 12;
int y = { 23 }; //Legal, no warning
int z = { { 34 } }; //Legal, expect a warning
Structures and arrays can be initialized in their declarations using an initializer list. Unless designators are used, the components of an initializer correspond with the elements in the order they are defined and stored, thus all preceding values must be provided before any particular element’s value. Any unspecified elements are set to zero. Mentioning too many initialization values yields an error.
The following statement will initialize a new instance of the structure s known as pi:
struct s {
int x;
float y;
char *z;
};
struct s pi = { 3, 3.1415, "Pi" };
Designated initializers
Designated initializers allow members to be initialized by name, in any order, and without explicitly providing the preceding values. The following initialization is equivalent to the previous one:
struct s pi = { .z = "Pi", .x = 3, .y = 3.1415 };
Using a designator in an initializer moves the initialization "cursor". In the example below, if MAX
is greater than 10, there will be some zero-valued elements in the middle of a
; if it is less than 10, some of the values provided by the first five initializers will be overridden by the second five (if MAX
is less than 5, there will be a compilation error):
int a[MAX] = { 1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0 };
If an array has unknown size (i.e. the array was an incomplete type), the number of initializers determines the size of the array and its type becomes complete:
int x[] = { 0, 1, 2 } ;
Compound designators can be used to provide explicit initialization when unadorned initializer lists might be misunderstood. In the example below, w
is declared as an array of structures, each structure consisting of a member a
(an array of 3 int
) and a member b
(an int
). The initializer sets the size of w
to 2 and sets the values of the first element of each a
:
struct { int a[3], b; } w[] = { [0].a = {1}, [1].a[0] = 2 };
This is equivalent to:
struct { int a[3], b; } w[] =
{
{ { 1, 0, 0 }, 0 },
{ { 2, 0, 0 }, 0 }
};
There is no way to specify repetition of an initializer in standard C.
Compound literals
It is possible to borrow the initialization methodology to generate compound structure and array literals:
int* ptr;
ptr = (int[]){ 10, 20, 30, 40 };
struct s pi;
pi = (struct s){ 3, 3.1415, "Pi" };
Compound literals are often combined with designated initializers to make the declaration more readable:
pi = (struct s){ .z = "Pi", .x = 3, .y = 3.1415 };