C struct initialization using labels. It works, but how? C struct initialization using labels. It works, but how? c c

C struct initialization using labels. It works, but how?


Here is the section of the gcc manual which explains the syntax of designated initializers for both structs and arrays:

In a structure initializer, specify the name of a field to initialize with '.fieldname =' before the element value. For example, given the following structure,

 struct point { int x, y; };

the following initialization

 struct point p = { .y = yvalue, .x = xvalue }; 

is equivalent to

 struct point p = { xvalue, yvalue }; 

Another syntax which has the same meaning, obsolete since GCC 2.5, is 'fieldname:', as shown here:

 struct point p = { y: yvalue, x: xvalue };

The relevant page can be found here.

Your compiler should have similar documentation.


These are neither labels nor bitfields.

This is a syntax to initialize struct members dating back to the days before C99. It is not standardized but available in e.g. gcc.

typedef struct { int y; int x; } POINT;POINT p = { x: 1, y: 17 };

In C99, syntax for initializing specific struct members has been introduced for the first time in a standard, but it looks a little differently:

typedef struct { int y; int x; } POINT;POINT p = { .x = 1, .y = 17 };


Yes, as pointed out above, these are designated initializers, which are standard C, though you should switch to using periods instead of colons. And as you note, most of the books out there are still stuck somewhere around 1984 in their syntax and fail to mention them. More fun facts:

--When using designated initializers, everything not specified is initialized at zero. This helps with exceptionally large structs, e.g.:

typedef struct {   double a, b, c, d, e;   char label[100];} too_many_type;too_many_type tm = {.a = 1, .e = 2, .b=1.5};assert(tm.a + tm.b + tm.c + tm.d + tm.e == 4.5);assert(!strlen(label));

--Also, you can use the compound literal form to use this form on a non-initialization line, e.g.:

too_many_type tm2;tm2 = (too_many_type) {.a = 3, .e=6};

These are really great features, and are supported by every C compiler that I can think of, being that it's the standard. It's a shame that they're not so well known.