• fanf2 an hour ago

    The most common and idiomatic example that relies on a variable being in scope in its initializer is,

      struct something *foo = malloc(sizeof(*foo));
    
    But that isn’t, strictly speaking, self-referential. Here’s one that is…

    In BSD <sys/queue.h> there are a bunch of macros for various kinds of linked list.

    https://man.freebsd.org/cgi/man.cgi?query=STAILQ_HEAD_INIT

    https://cgit.freebsd.org/src/tree/sys/sys/queue.h

    The STAILQ macros define a singly-linked list where the head is a pair of pointers (simplified slightly):

      struct stailq_head {
        struct stailq_elem *stqh_first;
        struct stailq_elem **stqh_last;
      }
    
    • a pointer to the first element, which is NULL when the list is empty

    • a pointer to the NULL pointer that terminates the list

    The last pointer allows fast appends, O(1) instead of O(n).

    When you initialize the head, the last pointer needs to point to the first pointer. The STAILQ_HEAD_INITIALIZER() macro does basically:

      struct stailq_head head = {
        NULL,
        &head.stqh_first,
      };
    
    There, head refers to itself!

    To append an element, the STAILQ_INSERT_TAIL() macro does basically:

      elem->next = NULL;
      *head.sthq_last = elem;
      head.sthq_last = &elem->next;
    
    So normally the last pointer points into an element; the last pointer points into the head only in an empty list.
    • uecker 2 hours ago

      The traditional use case are circular linked lists or similar data structures.

      struct foo { struct foo *next; } x = { .next = &x };

      • Joker_vD 4 hours ago

        It's allowed because it's in the spirit of C: both allowing and prohibiting it is almost equally easy, and it's also sometimes useful, so it's allowed. Now, there is a way [0] to statically check whether self-referential value initialization is well-founded or not but... it's kinda tricky to do and so, again in the C's spirit, such diagnostics is not required.

        [0] https://www.cl.cam.ac.uk/~jdy22/papers/a-right-to-left-type-...