14

I write a struct

struct Tree{
    struct Node *root;
    struct Node NIL_t;
    struct Node * const NIL;    //sentinel
}

I want

struct Node * const NIL = &NIL_t;

I can't initialize it inside the struct. I'm using msvs.

I use C, NOT C++. I know I can use initialization list in C++.

How to do so in C?

Celebi
  • 1,280
  • 3
  • 16
  • 25

4 Answers4

24

If you are using C99, you can used designated initializers to do this:

struct Tree t = { .root = NULL, .NIL = &t.NIL_t };

This only works in C99, though. I've tested this on gcc and it seems to work just fine.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 1
    +1 this would actually make for a good macro: `#define TreeDecl(id, rt) struct Tree id = { .root = rt, .NIL = &id.NIL_t }` – Chris Lutz Jan 13 '11 at 02:14
  • 4
    In C89 you can do `struct Tree t = { NULL, { 0 }, &t.NIL_t };` as long as 0 is a valid initializer for the first field in a struct Node. – Chris Dodd Jan 13 '11 at 02:38
  • Or, following on from @Chris Dodd's comment, you could rearrange the struct so that the `NIL` member came before the `NIL_t` member, then use `struct Tree t = { NULL, &t.NIL_t };` – caf Jan 13 '11 at 08:31
2

For those seeking a simple example, here it goes:

#include <stdio.h>

typedef struct {
    const int a;
    const int b;
} my_t;

int main() {
   my_t s = { .a = 10, .b = 20 };
   printf("{ a: %d, b: %d }", s.a, s.b);
}

Produces the following output:

{ a: 10, b: 20 }
Erik Campobadal
  • 867
  • 9
  • 14
1

A structure defines a data template but has no data itself. Since it has no data, there's no way to initialize it.

On the other hand, if you want to declare an instance, you can initialize that.

struct Tree t = { NULL, NULL, NULL };
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 1
    `NIL_t` is a `struct Node`, not a `struct Node *`, so it probably won't be initialized as `NULL`. I'd also recommend making an `struct Tree *init(...)` function (or a `void init(struct Tree *t, ...)` function if you prefer, or a macro) to do this kind of work for you. – Chris Lutz Jan 13 '11 at 02:07
  • @Chris: Right you are. Must've missed that. I guess you can probably only assign a structure to another structure after both have been declared. – Jonathan Wood Jan 13 '11 at 02:38
  • @Jonathan - For nested `struct`s you could use `struct Tree t = { NULL, { /* struct Node contents here */ }, NULL }` (or `&t.NIL_t` for the last one.) – Chris Lutz Jan 13 '11 at 02:41
  • @Chris: That's what I thought at first. But if that member is a structure of the same type, then the syntax would be infinitely recursive. No, I don't think that's going to work. – Jonathan Wood Jan 13 '11 at 02:57
  • @Jonathan - They're not. This is a `struct Node` inside a `struct Tree`. Not infinitely recursive in this case. (In the case that it is infinitely recursive, this would be a problem. But that's not the OP's case.) – Chris Lutz Jan 13 '11 at 02:59
  • @Chris: Looks like we don't know what Node is, so you may be right. – Jonathan Wood Jan 13 '11 at 03:03
  • @Jonathan - True. I'm making the assumption that if a `Tree` has a `Node` then a `Node` probably won't have any `Tree`s. – Chris Lutz Jan 13 '11 at 03:07
0

Maybe something like this will suffice?

struct {
    struct Node * const NIL;
    struct Node *root;
    struct Node NIL_t;
 } Tree = {&Tree.NIL_t};
gobernador
  • 5,659
  • 3
  • 32
  • 51
gumby
  • 21
  • 2