Initialization of c struct including union

I would like to initialize the ColourModelBlock of the following struct(s) with the following values:

extension_size = 4
model = 0
red = 0
green = 0
blue = 0

typedef struct {
  int                           extension_size;
  ColourModelData               ext;
} ColourModelBlock;

typedef struct {

  unsigned int      model; 
  union {

    struct {
       int               red;                  /* % */
       int               green;                /* % */
       int               blue;                 /* % */
    } rgb;

    struct {
       int               cyan;                 /* % */
       int               magenta;              /* % */
       int               yellow;               /* % */
       int               key;                  /* % */
    } cmyk;

    struct {
      int               hue;                  /* angle (degrees) */
       int               saturation;           /* % */
       int               value;                /* % */
    } hsv;

    char bytes[16];
    int  words[4];
  } data;
} ColourModelData;

The task seems simple but I tried to set the values directly (which worked for extension_size and model but I didn't know how to set the union values) or by using memcpy of a int array.

But I am quite new to C so I just may have messed it up.


  • First, you must declare ColourModelBlock before you use it in defining ColourModelBlock.

    Then, there are several choices about how to initialize a ColourModelBlock. First, to initialize structures, you can just list their values in braces. When unions are involved, the first member of the union is initialized:

    ColourModelBlock x = { 4, { 0, {{ 0, 0, 0 }} } };

    Here the inner braces follow the structure of ColourModelBlock, using a { for each contained struct or union. The compiler will accept the code without those braces and initialize in the same order, but it may warn you, and it is better to use the braces as it will help catch errors.

    Second, you can use member names to indicate which member you are initializing with each value. This would also allow you to initialize unions via a member other than the first, although that is not done here:

    ColourModelBlock x = {
            .extension_size = 4,
            .ext = {
                .model = 0,
                .data.rgb = { 0, 0, 0 }

    Note the above actually uses a combination of methods. Most members are initialized by name, called a designated initializer. But .data.rgb names a union and then initializes its members with a list, as in the first method. That may be natural in this case where the rgb member is thought of as a triple.

    You can also define an object and then give it values using assignment statements. The syntax above is for initialization. Assignments require different syntax:

    ColourModelBlock x;
    x.extension_size = 4;
    x.ext.model = 0;
    x.ext.data.rgb.red   = 0;
    x.ext.data.rgb.green = 0;
    x.ext.data.rgb.blue  = 0;

    You can use a compound literal to use the initialization syntax in an assignment. To create a compound literal and use it in an assignment, use any of the initialization lists above and put the type name in parentheses in front of, then use that as the right-hand side of an assignment:

    x = (ColourModelBlock) { 4, { 0, {{ 0, 0, 0 }} } };

    Finally, since most of the values you want to use as initial values are zero, you can omit them. If a structure is being initialized, and explicit values are not given for all members, the members without explicit values are initialized to zero (or, for pointers, to a null pointer):

    ColourModelBlock t = { 4 };