I would like to initialize a NULL terminated array of pointer to struct using compound literals.
Currently, I achieve this by:
struct object
{
int data1;
char data2;
};
struct object *object_array[] =
{
&(struct object) {1, 2},
&(struct object) {3, 4},
&(struct object) {5, 6},
&(struct object) {7, 8},
&(struct object) {9, 10},
NULL,
};
But, specifying (struct object) is very verbose.
Is there a way to make my code look something like this:
struct object
{
int data1;
char data2;
};
struct object *object_array[] =
{
&{1, 2},
&{3, 4},
&{5, 6},
&{7, 8},
&{9, 10},
NULL,
};
1 Answer 1
You could use a temporary helper macro:
struct object
{
int data1;
char data2;
};
#define OB(data1, data2) &(struct object) {data1, data2}
struct object *object_array[] =
{
OB(1, 2),
OB(3, 4),
OB(5, 6),
OB(7, 8),
OB(9, 10),
NULL
};
#undef OB
This is just a more concise way to do what was done in first example.
answered Jul 19, 2025 at 10:09
Tom Karzes
24.3k3 gold badges28 silver badges46 bronze badges
Sign up to request clarification or add additional context in comments.
6 Comments
0___________
hiding
& in macro is not the very best ideaTom Karzes
It's fine for something like this. This isn't a general-purpose expression macro. It's very specific to this one use, and is discarded after that use. It's only being used in an initialization, not in actual code. And it solves this specific problem. Sure, you could remove the
& from the macro and instead put it in each initializer, but I don't think that would be an improvement.Lundin
I would agree that this is bad practice, all it achieved is to invent some secret macro language local to the project. It makes the code less readable than the original.
Tom Karzes
For a small table, I'd agree with you. But for a large table, it's more readable to restrict the table to the relevant data and eliminate everything else. In that case, there's no harm in using a simple temporary macro to make it easier to maintain. Sometimes it helps to think outside of the language.
Lundin
If macros are to be brought in, it should at least be X-macros which is a standardized design pattern. Moving the data to an X-macro list would be better - it will not increase readability but it will make everything much more flexible.
Tom Karzes
If variable names and declarations were involved, that might make sense. But in this case, all it is is a sequence of structure initializers. The added generality of an X macro doesn't buy anything, and it would require the initializer list to defined as one big giant ugly multi-line macro that's later instantiated. It's cleaner to just have them in an ordinary initializer list. An X macro might make sense if the same initializer list also needed to be used for, say, a sequence of assignments. But I don't see that happening for this application.
lang-c
&when you actually need to pass a pointer?NULLpointer terminated? Are you using an external third-party API that requires pointers andNULLpointer termination? Can't there be a special termination object (where both values in the structure are something they can't be otherwise)? Can't you pass the number of elements (easily calculated) to the functions that need to use the array? There's a lot of information left out of the question.