Размер составного литерального массива
Я пытаюсь статически выделить некоторые структуры, каждая из которых содержит два члена: указатель на массив структур и размер этого массива.
Вот рабочая версия кода:
#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)
};
Но вместо того, чтобы определять массив отдельно, а затем ссылаться на этот массив при определении структуры, я хотел бы инициализировать указатель литералом массива, чтобы он содержал все это в определении структуры ради того, что я считаю повышенной читабельностью.:
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 */
};
Можно ли автоматически получить размер этого массива литерала во время компиляции? (Или я злоупотребляю языком и усложняю ситуацию?)
РЕДАКТИРОВАТЬ: Основываясь на ответе Олафа на аналогичный вопрос и комментарии Джона Боллинджера, вот что я закончил:
#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
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++;
}
}