Sizeof array literal array

I am trying to statically highlight some structures, each of which contains two elements: a pointer to an array of structures and the size of this array.

Here's the working version of the code:

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

struct conf_element {
        char *key;
        enum conf_elem_type val_type;
        void *val_p;
        tok_t *(*fn_p)(const char *js, jsmntok_t *tok);
};

struct conf_schema {
        struct conf_element *conf_elems;
        size_t size;
};

struct conf_element conf_schema_antennae_elems[] = {
        {"key1_nm", LEAF_INT, NULL, NULL},
        {"key2_nm", LEAF_INT, NULL, NULL}
};

struct conf_schema conf_schema_antennae = {
        conf_schema_antennae_elems,
        ARRAY_SIZE(conf_schema_antennae_elems)
};

Instead of defining the array separately and then referring to this array when defining the structure, I would like to initialize the pointer with an array literal so that it contains all this in the structure definition for the sake of what I consider to increase readability:

struct conf_schema conf_schema_antennae = {
        (struct conf_element []) {
                {"key1_nm", LEAF_INT, NULL, NULL},
                {"key2_nm", LEAF_INT, NULL, NULL}
        },
        /* the size of that ^ compound literal goes here */
};

Is it possible to automatically get the size of this array literal at compile time? (Or am I abusing the language and making things harder than they should be?)

EDIT: Based on Olaf's answer to a similar question and a comment by John Bollinger, here's what I ended up with:

#define S(arr) {arr, ARRAY_SIZE(arr)}

struct conf_schema conf_schema_antennae = S((
        (struct conf_element []) {
                {"key1_nm", LEAF_INT, NULL, NULL},
                {"key2_nm", LEAF_INT, NULL, NULL}
        }
));

#undef S
+4
1

, .

struct conf_element *conf_elems - , ARRAY_SIZE .

, -g. __compond_literal.###.

: ? , :

struct conf_schema conf_schema_antennae = {
        (struct conf_element []) {
                {"key1_nm", LEAF_INT, NULL, NULL},
                {"key2_nm", LEAF_INT, NULL, NULL},
                {0, 0, 0, 0} /* Place holder for the end of the array */
        }
};

void client_code ()
{
    struct conf_element *p_elems = conf_schema_antennae.conf_elems;

    while (p_elems->key)
    {
     /* ... */
     p_elems++;
    }
}
+1

Source: https://habr.com/ru/post/1662305/


All Articles