I'm trying to statically allocate some structures, each containing two members: a pointer to an array of structures, and the size of that array.
Here's a 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)
};
But rather than defining the array separately and then referencing that array when defining the structure, I'd like to initialize the pointer with an array literal in order to contain it all in the structure definition for the sake of what I believe to be increased 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 that 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 John Bollinger's comment, 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
You can't know know the size of a compound literal array, because its variable name is hidden.
Also
struct conf_element *conf_elemsis a pointer and the macroARRAY_SIZEcannot measure the length of the real array.You can see the name of the hidden variable if compiled with
-g. It will show in the debug information of the executable a variable named__compond_literal.###.I suggest you a workaround: Do you really need to know the size of it in the client code? If not, try this: