When initializing an object of struct or union type, the initializer must be a non-empty, brace-enclosed, comma-separated list of initializers for the members:
= { expression , ... } | (until C99) | |
= { designator(optional) expression , ... } | (since C99) |
where the designator is a sequence (whitespace-separated or adjacent) of individual member designators of the form .
member and array designators of the form [
index ]
.
All members that are not initialized explicitly are initialized implicitly the same way as objects that have static storage duration.
When initializing a union, the initializer list must have only one member, which initializes the first member of the union unless a designated initializer is used (since C99).
union { int x; char c[4]; } u = {1}, // makes u.x active with value 1 u2 = { .c={'\1'} }; // makes u2.c active with value {'\1','\0','\0','\0'}
When initializing a struct, the first initializer in the list initializes the first declared member (unless a designator is specified) (since C99), and all subsequent initializers without designators (since C99)initialize the struct members declared after the one initialized by the previous expression.
struct point {double x,y,z;} p = {1.2, 1.3}; // p.x=1.2, p.y=1.3, p.z=0.0 div_t answer = {.quot = 2, .rem = -1 }; // order of elements in div_t may vary
A designator causes the following initializer to initialize the struct member described by the designator. Initialization then continues forward in order of declaration, beginning with the next element declared after the one described by the designator. | (since C99) |
It's an error to provide more initializers than members.
If the members of the struct or union are arrays, structs, or unions, the corresponding initializers in the brace-enclosed list of initializers are any initializers that are valid for those members, except that their braces may be omitted as follows:
If the nested initializer begins with an opening brace, the entire nested initializer up to its closing brace initializes the corresponding member object. Each left opening brace establishes a new current object. The members of the current object are initialized in their natural order, unless designators are used (since C99): array elements in subscript order, struct members in declaration order, only the first declared member of any union. The subobjects within the current object that aren't explicitly initialized by the closing brace are implicitly initialized.
struct example { struct addr_t { uint32_t port; } addr; union { uint8_t a8[4]; uint16_t a16[2]; } in_u; }; struct example ex = { // start of initializer list for struct example { // start of initializer list for ex.addr 80 // initialized struct's only member }, // end of initializer list for ex.addr { // start of initializer-list for ex.in_u {127,0,0,1} // initializes first element of the union } };
If the nested initializer does not begin with an opening brace, only enough initializers from the list are taken to account for the elements or members of the member array, struct or union; any remaining initializers are left to initialize the next struct member:
struct example ex = {80, 127, 0, 0, 1}; // 80 initializes ex.addr.port // 127 initializes ex.in_u.a8[0] // 0 initializes ex.in_u.a8[1] // 0 initializes ex.in_u.a8[2] // 1 initializes ex.in_u.a8[3]
The order of evaluation of the subexpressions in any initializer is indeterminately sequenced:
int n = 1; struct {int x,y;} p = {n++, n++}; // unspecified, but well-defined behavior: // n is incremented twice in arbitrary order // p equal {1,2} and {2,1} are both valid
In C, the braced list of initializers cannot be empty (note that C++ allows empty lists, and also note that a struct in C cannot be empty):
struct {int n;} s = {0}; // OK struct {int n;} s = {}; // Error: initializer-list cannot be empty struct {} s = {}; // Error: struct cannot be empty, initializer-list cannot be empty
As with all other initialization, every expression in the initializer list must be a constant expression when initializing arrays of static or thread-local storage duration:
The initializer list may have a trailing comma, which is ignored.
#include <stdio.h> #include <time.h> int main(void) { char buff[70]; // designated initalizers simplify the use of structs whose // order of members is unspecified struct tm my_time = { .tm_year=112, .tm_mon=9, .tm_mday=9, .tm_hour=8, .tm_min=10, .tm_sec=20 }; strftime(buff, sizeof buff, "%A %c", &my_time); puts(buff); }
Possible output:
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/c/language/struct_initialization