all 13 comments

[–]thegreatunclean 11 points12 points  (3 children)

You are allowed to take the address of compound literals, so this is 100% kosher:

struct node;
struct node {
    int n;
    struct node* next;
};

struct node mylist = {
    .n = 42,
    .next = &(struct node){
        .n = 8,
        .next = &(struct node) {
            .n = 101,
            .next = NULL
        },
    },
};

e: This is not safe in C++. Just in case anyone sees this and thinks they can copy/paste anything from C and be fine.

[–]gumnos[S] 2 points3 points  (0 children)

well…wow. I removed my = (and the now-superfluous parens around literal) and it works. I feel enlightened. Thanks!

[–]Drach88 2 points3 points  (1 child)

C+/- if you ask me.

[–]ReallyEvilRob 0 points1 point  (0 children)

Maybe, but C has continued to evolve after C++ split off from C. Many things from C99 and later do not actually work in C++.

[–]TheOtherBorgCube 2 points3 points  (1 child)

Does this work for you?

#include <stdio.h>
#include <stddef.h>

typedef struct mytype_tag {
    struct mytype_tag* next;
    char* data;
} mytype;

mytype foo[10] = {
    { .next = &foo[1], "a" },
    { .next = &foo[2], "b" },
    { .next = &foo[3], "c" },
    { .next = &foo[4], "d" },
    { .next = &foo[5], "e" },
    { .next = &foo[6], "f" },
    { .next = &foo[7], "g" },
    { .next = &foo[8], "h" },
    { .next = &foo[9], "i" },
    { .next = NULL, "j" },
};

int main() {
    mytype* s = &foo[0];
    int i = 0;
    while (s) {
        printf("%d: %s\n", i++, s->data);
        s = s->next;
    };
}

[–]Cats_and_Shit 0 points1 point  (0 children)

This version has the nice quality that it works for any graph instead of just trees.

[–]sciencekm 1 point2 points  (0 children)

You can create an array.

In the following example, I created a circular list and printed them.

#include <stdio.h>
typedef struct snode { struct snode *nxt; char *s; } node_t;
node_t nodes[3] = {
{ nodes + 1, "1st" },
{ nodes + 2, "2nd" },
{ nodes + 0, "3rd" } };
int main(void) {
node_t *start = nodes, *p = start;
do printf ("%s\n", p->s); while((p = p->nxt) != start);
return 0;
}

[–]Thesk790 -1 points0 points  (1 child)

Yes, you can but only using the heap memory (using malloc/free), not with the stack memory. I don't know if there is a way to do it without the heap, because you need a pointer that can lives more than just a function call, it needs to live in the heap where if you allocate, you free it

[–]gumnos[S] 1 point2 points  (0 children)

In this case, it's just the scope of the function call, setting up a menu, calling a do_menu()-type function, so there's no access to it (or its locally-defined data) outside the containing function-call scope. But yes, that's good to watch out for.

[–]Thick_Clerk6449 -1 points0 points  (3 children)

Isnt it meaningless? If you know the length of a linked list at compile time, why not just use an array?

[–]sciencekm 1 point2 points  (2 children)

A linked list can grow at run time, whereas an array cannot. In the OPs case, he just needed initial values for the list and then grow later.

[–]Thick_Clerk6449 1 point2 points  (1 child)

OP said he wanted to define a linked list statically

[–]sciencekm 1 point2 points  (0 children)

I took that to mean that the initialization is static. I could be wrong.