Can you initialize a static linked list in C?

Updates:

  • 2020-04-30 – Added missing semicolon in code and updated example.

NOTE: This article was originally written a few years ago, so some references may be out of date.

I have been enjoying working on the SirSound project the past month, as well as some fun challenges at my day job. Every now and then I run into something I’d like to do that is not doable in C, or doable but not proper to do in C, or … maybe doable. It’s sometimes difficult for me to find answers when I do not know how to ask the question.

With that said, I have a C question for anyone who might be able to answer it.

Using my multi-track music sequencer as an example, consider representing data like this:

[sequence]
  [track]
    [note /]
    [note /]
    [note /]
  [/track]
  [track]
    [note /]
    [note /]
    [note /]
  [/track]
[/sequence]

It’s easy to create a sequence like this in C. Here’s some pseudo code:

track1 = { C, C, C, C };
track2 = { E, E, E, E };
sequence1 = { track1, track 2};

I thought there might be a clever way to do all of this with one initializer.  If I treat the data like nested XML (like the first example), I thought it might be possible to do something like this:

typedef struct SentenceStruct SentenceStruct;

struct SentenceStruct
{
  char           *Word;
  SentenceStruct *Next;
};

Something like this allows me to represent that tree of data very easily, and I find many examples of building things like this in C code:

int main()
{
   SentenceStruct Word1;
   SentenceStruct Word2;
   SentenceStruct Word3;

   Word1.Word = "sequence";
   Word1.Next = &Word2;

   Word2.Word = "track";
   Word2.Next = &Word3;

   Word3.Word = "note1";
   Word3.Next = NULL;

   SentenceStruct *Word;

   Word = &Word1;

   while( Word != NULL )
   {
      printf("%s ", Word->Word);
      if (Word->Next == NULL) break;
      Word = Word->Next;
   }
   printf("\n");

   return EXIT_SUCCESS;
}

This creates a single linked list of words, then prints them out.

I thought it might be possible to initialize the whole thing, like this:

 SentenceStruct sentence =
 {
   { "kitchen", { "light", { "ceiling", { "on", NULL }}}};
 }

…though the address of “light” is quite different than the address of a structure which contains a pointer that should point to “light”.

I was going to make each one a pointer to an array of words, so I could have a tree of words like the earlier example (with kitchen/light and kitchen/fan):

typedef struct SentenceStruct SentenceStruct;

struct SentenceStruct
{
  char *Word;
  SentenceStruct *Next[];
}

Does anyone know how (or if) this can be done in C?

Thoughts?

5 thoughts on “Can you initialize a static linked list in C?

  1. Darren

    The code below seems to work. The macro makes the initializer a bit less cluttered. Of course you do need to add or remove a closing brace on the last line for each word added or removed.

    typedef struct SentenceStruct SentenceStruct;

    struct SentenceStruct
    {
    char *Word;
    SentenceStruct *Next;
    };

    #define WORD(s) &(SentenceStruct){s

    SentenceStruct *sentence =
    WORD(“kitchen”), WORD(“light”), WORD(“ceiling”), WORD(“on”), NULL
    }}}};

    Reply
    1. Allen Huffman Post author

      That’s really cool. I was looking at a way to do this for an Arduino music sequencer. I also looked into it when I was implementing CoAP protocol. It works like URL paths. Maybe one device had a few lights and a fan and a temperature sensor on it:

      /light/0
      /light/1
      /light/2
      /fan/0
      /thermometer/0

      I could POST to that device “/light/0/on” or “/light/2/off” to have it happen. I could GET “/thermometer/0” and get back a temperature.

      To create a list of endpoints without redundancy I was trying to do them like:

      light
            0
            1
            2
      fan
            0
      thermometer
            0

      Now that you’ve shown me how to string things together, I’m going to see if I can use that to define it like that.

      Reply

Leave a Reply to Allen Huffman Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.