I'm trying to declare some constant data structures in my code, ideally without having to declare subelements (this is a follow-on from a previous question about multiple lists of strings: different length arrays) ... as per my previous question I can get it to work by declaring bits individually, but can't declare it all in one go.
I should add, I need a pointer to the data structure (the pointer will be in a different linker section so I can discover them automatically)...
This works...
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;
But this generates an error about non-static initialisation of a flexible array member..
const struct cpl *xx = &(const struct cpl){ 2, "thisa", "thisb", { "new", "item", "here", NULL } };
I suspect the answer (assuming it is possible) is similar to before, by adding some kind of casting to it, but I've tried everything I can think of.
In this case I probably can get by with the first version, but I'd rather not if I can avoid it.
Any help appreciated.
Flexible array members were probably intended to mainly be used for dynamic memory allocation, but there's nothing saying that they can't be used in other contexts. However, they cannot be initialized and that is the problem here. It may be possible to initialize them through some gcc extension.
Which in turn means you can't declare a
conststruct with internal linkage and use a flexible array member at the same time, because there is then no standard way to assign a value to it. If we could live with not having itconstand internal linkage both at once and instead only access it through aconstqualified pointer, there are some possible dirty work-arounds... what follows next in this answer isn't really recommended practice.If we replace the
structwith aunionallocating enough memory, then put an anonymous struct inside thatunion, then it is probably well-defined (or at least implementation-defined behavior) to use it.Initialize everything but the flexiable array member (and by all means keep internal linkage if we fancy):
Init the flexible array member in run-time:
Only access this through a
constqualified pointer, as replacement for the lostconst-ness:Full program:
Quite ugly but I can't really come up with any reasons why this code would not be well-defined. (If someone does, please leave a comment.)