tags:

views:

112

answers:

2

I am writing a LinkedList in C, the below code represent my Node definition.

typedef struct {
    int value;
    struct Node* next;
    struct Node* prev;
} Node;

I understand (or think that I do) that struct Node not the same as typedef struct Node. Granted my code compiles and runs as it's supposed to, however, I get a lot of warnings when assigning next and prev (warning: assignment from incompatible pointer type). I am guessing that this has to do with how I'm defining them in the Node structure. I uploaded the full source here

So, if that is indeed the problem, how should I define next and prev inside the typedef struct Node?

I was worried this may be a repost, but couldn't quite find what I was looking for. Thanks.

+6  A: 

You need to do it in this order:

typedef struct Node Node;

struct Node
{
  int value;
  Node *next;
  Node *prev;
};

That doesn't do exactly what you asked, but it solves the problem and is how this generally is done. I don't think there's a better way.

This kind of forward declaration has a second usage, in data hiding. If the list was implemented in a library, you could have just the typedef in the public header, along with functions like:

Node * list_new(void);
Node * list_append(Node *head, Node *new_tail);
size_t list_length(const Node *head);

This way, users of the library don't have easy access to the internals of your library, i.e. the fields of the Node structure.

unwind
Yes. A forward declaration ( http://en.wikipedia.org/wiki/Forward_declaration ) is exactly what is needed.
Eric Towers
Oh wow. I think I tried every combination except that one! thanks! warnings all gone! :)
KennyCason
Right, I'm aware of forward declarations and used them throughout C++, but just never had this particular circumstance come up before, let alone with typedef/structs :)
KennyCason
Actually it would have worked to just add `Node` after the first `struct` in OP's code.
R..
@R.. Thanks That worked for me as well. Is there a preference between the two methods mentioned?
KennyCason
Either is just as good. Personally I usually only use a separate forward declaration and typedef (as in unwind's answer) is when I want to put the declaration in a header and the definition in an implementation file.
R..
Thanks. that makes sense.
KennyCason
+1  A: 

Another acceptable way and with the least change to OP's code is the following:

typedef struct NodeT {
    int value;
    struct NodeT * next;
    struct NodeT * prev;
} Node;

Note the introduction of NodeT and its usage in next and prev until Node is available.

ArunSaha
This is actually what I ended up doing in my implementation. :) per @R..'s comment
KennyCason