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.

Designator list syntax for structures and unions

Read syntax diagramSkip visual syntax diagram{ ,.member=expression }

Designator list syntax for arrays

Read syntax diagramSkip visual syntax diagram{ ,[array subscript]=expression }
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.