summit.novell.com)
dmk.com)
20 May, 1995
This document specifies the form and interpretation of a pure extension to the language portion of the C standard to provide important additional flexibility to initializers.
This document, although extending the C standard, still falls within the scope of that standard, and thus follows all rules and guidelines of that standard except where explicitly noted herein.
All references to clauses of the ISO standard and to sections of the former X3.159 standard will be presented in pairs. For example, ISO §6.4 (X3.159 §3.4) references constant expressions.
The syntax for initializers in ISO §6.5.7 (X3.159 §3.5.7) is changed to the following, and the constraints and semantics are augmented by the following:1
No initializer shall attempt to provide a value for an object not contained within the entity being initialized.2
If a designator has the form
then the current object (defined below) shall have array type and the expression shall be an integral constant expression that shall evaluate to a valid index for that array. If the array is of unknown size, any nonnegative index value is valid.
If a designator has the form
then the current object (defined below) shall have structure or union type and the identifier shall be a member of that type.
Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first member of a union.3 In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization continues forward, as normal, after the designated initializer.4 (The designation can be thought of as a “goto” within the current object.)
Each designator list begins its description with the current object associated with the closest-surrounding brace pair. Each item in the designator list (in order) specifies a particular member of its current object and changes the current object for the next designator (if any) to be that member.5 The current object that results at the end of the designator list is the subobject to be initialized by the following initializer.
The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer.6
Arrays can be initialized to correspond to the elements of an enumeration by using designators:
enum { Mem_One, Mem_Two, /*...*/ };
const char *nm[] = {
[Mem_Two] = "Mem Two",
[Mem_One] = "Mem One",
/*...*/
};
Structure members can be initialized to nonzero values without depending on their order:
div_t answer = { .quot = 2, .rem = -1 };
Designators can be used to provide explicit initialization when unadorned initializer lists might be misunderstood:
struct { int a[3], b; } w[] = { [0].a = {1}, [1].a[0] = 2 };
Space can be “allocated” from both ends of an array by using a single designator:
int a[MAX] = {
1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
};
In the above, if MAX is greater than ten, there will be some zero-valued elements in the middle; if it is less than ten, some of the values provided by the first five initializers will be overridden by the second five.
Finally, any member of a union can be initialized:
union { /*...*/ } u = { .any_member = 42 };