6

this is probably really simple, but how can I get a struct x to be in struct x in C? So for example:

typedef struct _Node {
    Node node;
} Node;

I've done some research and tried using pointers, like this:

typedef struct _Node {
    struct Node *node;
} Node;

Although that leaves the variable node as a pointer, which I don't want, I just want it to be an instance of the Node struct. Thanks for any help. :)

EDIT:

Essentially what I'm trying to do is:

Node current = createNode(...);
while (true) {
    Node node = createNode(..., &current);
    addToList(node);
    current = somethingElse();
}

As you can probably imagine, I want a regular node to go into the createNode() function:

Node createNode(..., Node node) {}
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
Mr Cherno
  • 315
  • 3
  • 10
  • 14
    You can't do that. To understand recursion, you must first understand recursion. – DCoder Jun 08 '13 at 09:14
  • @DCoder So what would be the ideal work around? – Mr Cherno Jun 08 '13 at 09:14
  • 4
    Use pointers, like what you've found in your research – Tomer Arazy Jun 08 '13 at 09:15
  • 5
    If a variable of type `Node` contains a member of type `Node` called `node`, then that member also contains a member of type `Node` called `node`... there would be an infinite chain of them. And since there's nothing else in there, you could do nothing with this variable but follow the infinite chain to nowhere. –  Jun 08 '13 at 09:16
  • [Related](http://stackoverflow.com/questions/4094642/next-struct-item-incomplete-type) – David Ranieri Jun 08 '13 at 09:16
  • @TomerArazy If I use pointers, won't that mean that an instance of the variable it's pointing to is used, instead of a copy? So if I change the variable it points to, won't the pointer also change? How can I work around that? – Mr Cherno Jun 08 '13 at 09:17
  • Now you're getting closer to an actual question, but it's not making much sense. Show an example of using the struct with the pointer in it, and explain what you want it to do and how it's failing to do that, then maybe someone can help. –  Jun 08 '13 at 09:20
  • @WumpusQ.Wumbley I edited the question with an example. :) – Mr Cherno Jun 08 '13 at 09:26
  • @MrCherno in C++, you could solve that very robustly with a copy constructor. That would let you specify what should happen when a copy is created of an object (in this case, copy the pointed-to object as well, presumably). In C, you have to do this manually. Whenever a `Node` is copied, write additional code to fix up its internals. – jalf Jun 08 '13 at 09:36
  • I think that what you really want is something like a linked list. Check this out, read it, and probably you will find your answer: http://www.cprogramming.com/tutorial/c/lesson15.html – Lesswire Jun 08 '13 at 09:37
  • `createNode` definitely looks like it's trying to allocate a new node and append or prepend it to a linked list. But we only have a fragment of a program there, not an actual program with desired output and actual output we can compare. –  Jun 08 '13 at 18:59

2 Answers2

8
typedef struct node {
    struct node node;
} node_s;

This would lead to an "infinite recursion". In other words, its size would be infinite. The compiler cannot answer this question: how much memory to allocate? Therefore it will throw a diagnostic message.

That's why you have to use pointers to create self-referential types.

typedef struct node {
    struct node *node;
} node_s;

By the way, identifiers starting with an underscore followed by an underscore or capital letter are reserved to the implementation.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
md5
  • 23,373
  • 3
  • 44
  • 93
3

That isn't possible. Because that comes under incomplete type. No struct Node inside struct Node inside struct Node...and so on.... That makes your original structure incomplete. Hence incomplete type definition.

The reason is that.

  1. In order a field to be inside a structure, it has to be a known type.
  2. But by the time we see struct Node inside struct Node{} it isn't yet determined.
  3. It's only determined after scanning all definition of struct Node{} but that's only possible after knowing the type of struct Node inside which leads to a paradox.

But the case is different if you include struct Node *.

  1. When you reach struct Node *, you know it's a pointer type. That needs a fixed amount of storage no matter what the type of pointer is.
  2. So, it successfully scans it and finishes the definition of struct Node{}. Hence it's a complete type.
pinkpanther
  • 4,770
  • 2
  • 38
  • 62