复合字面量数组的大小

8
我正在尝试静态分配一些结构,每个结构包含两个成员:指向一组结构的指针和该数组的大小。这里是一个可行的代码示例:
#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 */
};

能否在编译时自动获取该数组文字的大小?(或者我是否滥用了语言,使事情变得比它们应该更困难?)

编辑:根据Olaf对类似问题的回答和John Bollinger的评论,这是我的最终方案:

#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
可能是在C语言中是否能将长的数组初始化简化为短的初始化列表?的重复问题。 - too honest for this site
2
如果你将问题简化成[mcve](最小完整可复制的例子),你最终会发现重复。我仍然认为我的答案是最清晰、最简单的解决方案,只需适应你的问题即可。如果字段不需要修改,应该正确使用“const”限定符。 - too honest for this site
1
这里唯一需要注意的是,当数组字面量用作像Olaf在他引用的答案中描述的宏的参数时,您需要将其括在(额外的)括号中。这些括号将防止字面量本身中的逗号被视为宏参数分隔符。 - John Bollinger
1个回答

3
您无法知道复合字面量数组的大小,因为其变量名是隐藏的。
此外,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++;
    }
}

你真的需要知道它的大小吗?-- 不用了,谢谢。 :-) - Peque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接