Search code examples
arrayscstructoperator-precedencedesignated-initializer

Can't understand this C syntax. Designated initialization of an array of structs?


Trying to learn the nuances of C, though I was doing well until I found this:

#define SOKOL_IMPL
#define SOKOL_GLES3
#include "sokol_gfx.h"
#include "sokol_log.h"
#include "emsc.h"

static struct {
    sg_pipeline pip;
    sg_bindings bind;
    sg_pass_action pass_action;
} state = {
    .pass_action.colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f } }
};

It's sample code from Sokol library: https://github.com/floooh/sokol-samples/blob/master/html5/triangle-emsc.c

I get that the first struct declaration also declares a variable "state", then I think this new variable is assigned to whatever is after "=" using a "designated init". What I don't understand is what .pass_action.colors[0] is.

I thought "colors" is a field inside pass_action, which in turn makes pass action a struct and colors should be an array. But, "colors" assignment uses designated inits idiomatic to structs again.

So, maybe .colors[0] is a field of .pass_action and also an array of structs, which have two fields: "load_action" and "clear_value". Is that correct? I need to be sure before making progress.

"Designated Inits": https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

UPDATE: sg_pass_action is declared here and "colors" type is defined a few lines above https://github.com/floooh/sokol/blob/6f8121e6aa523b0c0a3e9d7212073bab9a885e15/sokol_gfx.h#L2542

This has been pointed out to me elsewhere on reddit and clears everything up (I think). "colors" is an array of type "sg_color_attachment_action" which itself is a struct. And of size "SG_MAX_COLOR_ATTACHMENTS".


Solution

  • The unnamed struct has 3 members: pip, bind and pass_action. sg_pipeline and sg_bindings are probably typdef'ed structs but we cannot tell but we know that sg_pass_action is.

    The corresponding variable state implicitly initializes pip and bind to zero, and the member pass_action's member colors[0] is initialized with the compound value:

    { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f } }

    The members of pass_action colors is an array of structs with the members load_action and clear_value.

    clear_value is either an array of at least 4 elements, or is a struct with at least 4 members, probably of a floating point type.

    Something along these lines (where ? is required information that we cannot tell from the data provided):

    typedef struct {
        struct {
           ? load_action;
           float clear_value[4];
        } colors[?];
    } sg_pass_action;
    

    If you haven't run your program through the pre-processor (for exmaple cpp) and inspect the output.