Can only a typed union allow this type of declaration of array data in C?

I am trying to find a way to declare several data structures that are arrays of structures, where each subsequent array uses a part of the earlier one. which minimizes duplication. Thus, each element is declared only once.

So, conceptually imagine these four arrays, where the given element number that appears in both arrays is intended to represent the actual same, and not just another with the same value.

some_type group_A[] = { elt0, elt1, elt2, elt3, NULL }; some_type group_B[] = { elt0, elt1, elt2, elt3, // those are all A's elt4, elt5, NULL // these are new to B }; some_type group_C[] = { elt0, elt1, elt2, elt3, // those are all A's elt6, elt7, elt8, NULL // these are new to C }; some_type group_D[] = { elt0, elt1, elt2, elt3, elt4, elt5, // those are all B's elt9, elt10, elt11, NULL // these are new to D }; 

We can assume that some_type already a typedef for some kind of structure.

What I would like to do is to eliminate redundant ads because they seem untidy in general and because they open you up to update incoherence. Here is a more compact view where an entry in a group can be a normal element or it can be a reference to another array of such elements.

(You would be right to infer a NULL ponter at the end, that each array declaration, that each element is really a pointer to a structure of the same type.)

 some_type group_A[] = { elt0, elt1, elt2, elt3, NULL }; some_type group_B[] = { Group_A, elt4, elt5, NULL }; some_type group_C[] = { Group_A, elt6, elt7, elt8, NULL }; some_type group_D[] = { Group_B, elt9, elt10, elt11, NULL }; 

In other words, I want a way to declare that Group_B and Group_C both start with everything in Group_A, but then their elements after that, and that Group_D contains everything in Group_B (itself in turn, including everything in Group_A), and then adding your own elements.

I want this to be declarative, just a bunch of declarations of the array data that happens at compile time, and not at runtime, of the code to build the data structure.

This would be forbidden to recurs, at least in practice and at runtime.

Is there a good, declarative implementation similar to this array, or should I restore a more complex implementation of a dynamic data structure that is not fixed at compile time, as I prefer?

My guess is that the only thing that can be associated with a labeled pool.

 struct pointer_or_doublepointer { int which_kind; // 0 == .element is valid; 1 == .table is valid union { real_type * element; // valid only when which_kind == 0 real_type ** table; // valid only when which_kind == 1 }; } 

And then I just make some_type typedef for pointer_or_doublepointer .

Is this really the best way to establish something like this, or is there some other better and more direct solution that comes to mind? Again, remember that all this must be done through data declarations, not through code.

It should be in pure C, and not in C ++ or some other variant.

+4
source share
2 answers

Since you say that a link to other arrays will only be displayed at the beginning, an easy way to represent this is to keep this link separate from the rest of the elements:

 struct ElementList { struct ElementList *prefix; //Reference to elements of another array, or NULL some_type *elements; //additional elements }; 

This is a more limited union solution, but probably easier to use.

+1
source

is something like this work for you?

 #define GROUPA elt0, elt1, elt2, elt3 #define GROUPB GROUPA, elt4, elt5 #define GROUPC GROUPA, elt6, elt7, elt8 #define GROUPD GROUPB, elt9, elt10, elt11 some_type group_A[] = { GROUPA, NULL }; some_type group_B[] = { GROUPB, NULL }; some_type group_C[] = { GROUPC, NULL }; some_type group_D[] = { GROUPD, NULL }; #undef GROUPA #undef GROUPB #undef GROUPC #undef GROUPD 

I think this is an ideal case for using macros to avoid code duplication without causing code clarity.

+2
source

All Articles