我试图在我的代码中声明一些常量数据结构,理想情况下不必声明子元素(这是关于多个字符串列表的上一个问题的后续内容:不同长度数组)...根据我的上一个问题我可以通过单独声明位来使其工作,但不能一次性声明全部。
我应该添加,我需要一个指向数据结构的指针(指针将位于不同的链接器部分,以便我可以自动发现它们)...
这有效...
struct cpl {
int x;
char *a;
char *b;
char *list[];
};
const struct cpl one = { 1, "thisa", "thisb", { "one", "two", NULL }};
const struct cpl *xx = &one;
但这会生成有关灵活数组成员的非静态初始化的错误..
const struct cpl *xx = &(const struct cpl){ 2, "thisa", "thisb", { "new", "item", "here", NULL } };
我怀疑答案(假设可能)与之前类似,通过添加某种类型的转换来实现,但我已经尝试了我能想到的一切。
在这种情况下,我可能可以使用第一个版本,但如果我可以避免它,我宁愿不使用它。
任何帮助表示赞赏。
灵活数组成员可能主要用于动态内存分配,但没有说它们不能在其他上下文中使用。但是,它们无法初始化,这就是这里的问题。可以通过一些 gcc 扩展来初始化它们。
这又意味着您不能声明具有内部链接的
const
结构并同时使用灵活的数组成员,因为没有标准方法为其赋值。如果我们可以同时拥有它 const
和内部链接,而只能通过 const
限定指针访问它,那么可能会有一些肮脏的解决方法......这个答案中接下来的内容不是真的推荐练习。
如果我们将
struct
替换为 union
并分配足够的内存,然后在该 union
中放入一个匿名结构,那么使用它时 可能 是明确定义的(或者至少是实现定义的行为)。
typedef union {
struct
{
int x;
char *a;
char *b;
char *list[];
};
unsigned char lots_of_memory[100];
} cpl;
初始化除灵活数组成员之外的所有内容(如果我们愿意,请务必保持内部链接):
static cpl one = { .x=1, .a="thisa", .b="thisb" };
在运行时初始化灵活数组成员:
memcpy(one.list, (char*[]){ "one", "two", NULL }, sizeof(char*[3]));
只能通过
const
限定指针访问它,作为丢失的const
-ness的替代:
const cpl *xx = &one;
完整节目:
#include <string.h>
#include <stdio.h>
typedef union {
struct
{
int x;
char *a;
char *b;
char *list[];
};
unsigned char lots_of_memory[100];
} cpl;
int main (void)
{
static cpl one = { .x=1, .a="thisa", .b="thisb" };
memcpy(one.list, (char*[]){ "one", "two", NULL }, sizeof(char*[3]));
const cpl *xx = &one;
for(size_t i=0; xx->list[i]!=NULL; i++)
{
puts(xx->list[i]);
}
}
相当难看,但我真的想不出任何原因来解释为什么这段代码没有明确定义。 (如果有人这样做,请发表评论。)