1

I want to declare a self-referential structure as below

    typedef struct
    {
            entry_t *entry;
            node_t *next;
    }node_t;

instead of as below for a linked-list

  struct node
  {
         entry_t *entry;
         struct node *next;
  }*head;

does this work in C? If no why not?

liv2hak
  • 14,472
  • 53
  • 157
  • 270
  • 4
    *does this work in C?* -- why not just try it first? – justin Oct 02 '12 at 05:17
  • @liv2hak: apparently you can somehow manage to do it (using an incomplete type and a forward-declaration); see my answer. –  Oct 02 '12 at 05:22

2 Answers2

6

It won't work, since the symbol/name node_t is unknown at the declaration of next:

typedef struct
{
    entry_t *entry;
    node_t *next; /* <-- Error: unknown type */
} node_t;

Your struct needs a name in its declaration in order to be "self referential". However, you can keep the typedef:

typedef struct node
{
    entry_t *entry;
    struct node *next; /* <-- type struct node is known */
} node_t;

Now you can use either struct node or node_t to create a new node.

Zeta
  • 103,620
  • 13
  • 194
  • 236
  • Just to add, C is different here from C++, where you do not need to use `typedef` specifically. In C, once `typedef` is encountered, `node_t` will be equivalent to `struct node`. – Deepanjan Mazumdar Oct 02 '12 at 05:17
  • @Zeta you can also use a forward declaration, see my answer. –  Oct 02 '12 at 05:22
  • @H2CO3: +1, but only if OP "*really, badly* want[s] that typedeffed name as early as declaring the structure itself", yes. Personally, I prefer to use the first variant you mentioned, as I like to fully define the structure before or at the same time I use a typedef. But I guess that's a question of coding style :D – Zeta Oct 02 '12 at 05:27
  • @Zeta me too, I prefer the complete-type one, but I wanted to answer OP's question instead of teaching him good practice :D –  Oct 02 '12 at 05:28
  • @Zeta, @H2CO3: actually, I think it's pretty common to put the `typedef struct foo foo_t;` line in a public header, leaving `foo_t` as an incomplete type. That works fine as long as the public interface only uses `foo_t*s`' and avoids having to put any details about `foo_t` in a public header. The actual `struct foo` definition can go in a library internal header. – rici Oct 02 '12 at 05:59
4

The version you mentioned for the 2nd time is widely used, you can make a typedef like

typedef struct some_struct_name {
    /* other fields, etc... */
    struct some_struct_name *next;
} *some_type;

If you really, badly want that typedeffed name as early as declaring the structure itself, you can use a forward declaration using an incomplete type:

typedef struct node *node_t;

struct node {
    int data;
    node_t next;
};

This is also accepted by C89:

enter image description here

Zeta
  • 103,620
  • 13
  • 194
  • 236
  • @caf you don't need to sniff at every and each thing I do. –  Oct 02 '12 at 05:35
  • 1
    no need to make the `typedef` a pointer to `struct`. Just a normal `typedef` as forward declaration of the `struct` and the `typedef` would do. – Jens Gustedt Oct 02 '12 at 05:57