Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to statically initialize a linked list in C?

Tags:

c

c11

I have a singly-linked list type that looks like this:

struct point { int x, y; };
struct point_list {
    struct point value;
    const struct point_list *next;
};

I want to statically initialize one of these lists, with maybe a few dozen entries. I want to write one item per line with consistent indentation, to make it easy to edit the list.

So far the best I've come up with is this:

const struct point_list *const my_list =
    &(const struct point_list) { .value = { 1, 2 }, .next =
    &(const struct point_list) { .value = { 3, 4 }, .next =
    &(const struct point_list) { .value = { 5, 6 }, .next =
    NULL
    }}};

But the downsides are:

  • When I add or remove items, I need to update the number of closing braces on the last line.
  • It might be hard to convince a code formatter to keep this style.

Is there a better way?

If we had recursive macros, maybe something like this could work:

const struct point_list *const my_list = POINT_LIST(
    ((struct point) { 1, 2 }),
    ((struct point) { 3, 4 }),
    ((struct point) { 5, 6 }),
);

If we could run code at compile time, maybe something like this could work:

#define array_length(X) (sizeof(X) / sizeof(X[0]))

constexpr const struct point_list *array_to_list(size_t length, struct point *values) { ... }

const struct point my_array[] = {
    { 1, 2 },
    { 3, 4 },
    { 5, 6 },
};
const struct point_list *const my_list = array_to_list(array_length(my_array), my_array);
like image 926
dpercy Avatar asked Feb 02 '20 00:02

dpercy


1 Answers

Rather than declaring my_list as a pointer, you can declare it as an array:

struct point_list const my_list[] = {
    { .value = { 1, 2 }, .next = &my_list[1] },
    { .value = { 3, 4 }, .next = &my_list[2] },
    { .value = { 5, 6 }, .next = NULL }
};

If you still want my_list to be a pointer, you can do something similar:

static struct point_list const my_list_data[] = {
    // ...
};
const struct point_list *const my_list = my_list_data;
like image 104
1201ProgramAlarm Avatar answered Sep 16 '22 12:09

1201ProgramAlarm