2

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,
};
7
  • 2
    My question is, why do you need an array of pointers? Why not an array of structure objects, and then use the pointer-to operator & when you actually need to pass a pointer? Commented Jul 19 at 10:25
  • 1
    If I want the array to be null terminated, I need an array of pointer. Commented Jul 19 at 10:39
  • 2
    The natural follow-up question then becomes, why do you need the array to be NULL pointer terminated? Are you using an external third-party API that requires pointers and NULL pointer 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. Commented Jul 19 at 10:52
  • 5
    This might be an XY probem. It's hard to tell. Giving us some more info might help. Commented Jul 19 at 11:13
  • 1
    There isn't any need for it to have null termination, it's just the behavior I wanted to have. And just to clarify, my question is purely about the syntax of compound literals. Commented Jul 19 at 12:14

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

hiding & in macro is not the very best idea
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.
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.
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.
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.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.