gcc: Designated Inits
1
1 6.27 Designated Initializers
1 ============================
1
1 Standard C90 requires the elements of an initializer to appear in a
1 fixed order, the same as the order of the elements in the array or
1 structure being initialized.
1
1 In ISO C99 you can give the elements in any order, specifying the array
1 indices or structure field names they apply to, and GNU C allows this as
1 an extension in C90 mode as well. This extension is not implemented in
1 GNU C++.
1
1 To specify an array index, write '[INDEX] =' before the element value.
1 For example,
1
1 int a[6] = { [4] = 29, [2] = 15 };
1
1 is equivalent to
1
1 int a[6] = { 0, 0, 15, 0, 29, 0 };
1
1 The index values must be constant expressions, even if the array being
1 initialized is automatic.
1
1 An alternative syntax for this that has been obsolete since GCC 2.5 but
1 GCC still accepts is to write '[INDEX]' before the element value, with
1 no '='.
1
1 To initialize a range of elements to the same value, write '[FIRST ...
1 LAST] = VALUE'. This is a GNU extension. For example,
1
1 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
1
1 If the value in it has side effects, the side effects happen only once,
1 not for each initialized field by the range initializer.
1
1 Note that the length of the array is the highest value specified plus
1 one.
1
1 In a structure initializer, specify the name of a field to initialize
1 with '.FIELDNAME =' before the element value. For example, given the
1 following structure,
1
1 struct point { int x, y; };
1
1 the following initialization
1
1 struct point p = { .y = yvalue, .x = xvalue };
1
1 is equivalent to
1
1 struct point p = { xvalue, yvalue };
1
1 Another syntax that has the same meaning, obsolete since GCC 2.5, is
1 'FIELDNAME:', as shown here:
1
1 struct point p = { y: yvalue, x: xvalue };
1
1 Omitted field members are implicitly initialized the same as objects
1 that have static storage duration.
1
1 The '[INDEX]' or '.FIELDNAME' is known as a "designator". You can also
1 use a designator (or the obsolete colon syntax) when initializing a
1 union, to specify which element of the union should be used. For
1 example,
1
1 union foo { int i; double d; };
1
1 union foo f = { .d = 4 };
1
1 converts 4 to a 'double' to store it in the union using the second
1 element. By contrast, casting 4 to type 'union foo' stores it into the
11 union as the integer 'i', since it is an integer. ⇒Cast to
Union.
1
1 You can combine this technique of naming elements with ordinary C
1 initialization of successive elements. Each initializer element that
1 does not have a designator applies to the next consecutive element of
1 the array or structure. For example,
1
1 int a[6] = { [1] = v1, v2, [4] = v4 };
1
1 is equivalent to
1
1 int a[6] = { 0, v1, v2, 0, v4, 0 };
1
1 Labeling the elements of an array initializer is especially useful when
1 the indices are characters or belong to an 'enum' type. For example:
1
1 int whitespace[256]
1 = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
1 ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };
1
1 You can also write a series of '.FIELDNAME' and '[INDEX]' designators
1 before an '=' to specify a nested subobject to initialize; the list is
1 taken relative to the subobject corresponding to the closest surrounding
1 brace pair. For example, with the 'struct point' declaration above:
1
1 struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };
1
1 If the same field is initialized multiple times, it has the value from
1 the last initialization. If any such overridden initialization has side
1 effect, it is unspecified whether the side effect happens or not.
1 Currently, GCC discards them and issues a warning.
1