c - Initializing constant struct containing pointer to its own type -


i'm having struct this:

typedef struct tree_s{     struct tree_s *a;     int b; }tree_t; 

which, @ moment, initializing in way:

tree_t branch_n = {     .a = null,     .b = 2 };  tree_t root = {     .a = (tree_t*) &branch_n,      .b = 1 }; 

now, annoys me have initialize lower branches before root because complete structure quite large, branches having branches on own, making code hard manage.

what this:

tree_t root = {     .a =       //the first branch      {                          .a =          //yet branch           { //since following array, need             // "a" above point first index              {                    .a = null,         //maybe have own branch                  .b = 3              },              {                  .a =                   {                      .a = null,     //and might have own branch                      .b = 5                  }                  .b = 4                }          }         .b = 2      },      .b = 1 }; 

how can achieve initialization this?

the main reason want enhance overview of code , visually see structure of "tree".

note structure of complete "tree" know start why consider structure constant. value b may changed @ time.

i quite new c language , first post on so, feel free edit or ask if havent been able make myself clear :)

option 1a — array

your 'tree' structure seems stuck rather linear shape, can use array around problem:

static const tree_t oak[] = {     { .a = &oak[1], .b = 20 },     { .a = &oak[2], .b = 15 },     { .a = null,    .b = 10 }, }; 

option 1b — tree built array

or given binary search tree structure:

#include <stdio.h>  typedef struct bst_t bst_t; struct bst_t {     int          data;     const bst_t *left;     const bst_t *right; };  static const bst_t bst[] = {     { .data = 30, .left = &bst[1], .right = &bst[2] },     { .data = 10, .left = &bst[3], .right = &bst[4] },     { .data = 50, .left = &bst[5], .right = &bst[6] },     { .data =  5, .left = &bst[7], .right = &bst[8] },     { .data = 20, .left =       0, .right = &bst[9] },     { .data = 40, .left =       0, .right =       0 },     { .data = 60, .left =       0, .right =       0 },     { .data =  2, .left =       0, .right =       0 },     { .data =  8, .left =       0, .right =       0 },     { .data = 28, .left =       0, .right =       0 }, };  static void print_in_order(const bst_t *bst) {     if (bst != 0)     {         printf("[");         print_in_order(bst->left);         printf("(%d)", bst->data);         print_in_order(bst->right);         printf("]");     } }  static void print_tree(const bst_t *bst) {     print_in_order(bst);     putchar('\n'); }  int main(void) {     print_tree(&bst[0]);     return 0; } 

this produces output:

[[[[(2)](5)[(8)]](10)[(20)[(28)]]](30)[[(40)](50)[(60)]]] 

option 2a — c99 compound literals

with c99 , compound literals, can write:

#include <stddef.h>  typedef struct tree_s{     struct tree_s *a;     int b; }tree_t;  tree_t root2 = {     .a = &(tree_t){ .a = null, .b = 2 }, .b = 1 };  tree_t root3 = {     .a = &(tree_t){ .a = &(tree_t){ .a = null, .b = 3 }, .b = 2 }, .b = 1 }; 

i'm not sure legible, compiles ok. on whole, prefer array notation, though.

this primary answer op wanted/used.


option 2b — failed attempt array initialization

attempting adapt revised data structure in question (bearing in mind 'tree' can created data structure singly-linked list), can (but not quite) this:

tree_t root4 = {     .a = &(tree_t)     {                          .a = (tree_t [])         {              (tree_t){                   .a = null,                 .b = 3             },             (tree_t){                 .a = &(tree_t)                 {                     .a = null,                     .b = 5                 },                 .b = 4               },         },  // line 47         .b = 2     },      .b = 1 }; 

gcc (i686-apple-darwin11-llvm-gcc-4.2 (gcc) 4.2.1 (based on apple inc. build 5658) (llvm build 2336.11.00)) on mac os x 10.8.4 complains:

tree.c:47: error: initializer element not constant tree.c:47: error: (near initialization ‘(anonymous)’) 

where line 47 marked — end of array of structures. may missing obvious. did try &(test_t[]){ ... }[0], got same warning.

i'm not @ sure how tell particular pointer pointer start of array rather single tree_t element, unless add field indicate difference (or b field somehow encoded indicate whether a pointer single item or pointer array).


Comments