1

I have seen questions talking about structs that have pointers to each other, I tried a lot of things but I just can't solve my problem. My brain is just, burning!

I have two different structures/types: set_t and node_t

#ifndef _SETH_
#define _SETH_    
#include "node.h"
#include "list.h"

typedef struct {
    list_t* list;

}set_t;

set_t* createSet(node_t*);
set_t* findSet(node_t*);
set_t* unionSet(node_t*, node_t*);

#endif

I don't have any node_t in my set_t structure, but I use node_t as parameters, so I include node.h as you can see. List is a linked list of nodes, but this is not linked to my problem for now.

#ifndef _NODEH_    
#define _NODEH_

//?? #include "set.h"
typedef struct set_t s;

typedef struct  node_t{
    int color;
    int dist;
    int key;
    int date;
    int end;
    s* set;
    struct node_t* father;
}node_t;

node_t* createNode(int);
#endif

In the beggining, I use to include set.h in node.h, because I'm using a set in my node struct. But I had some kind of "loop" with the includes. So I'im trying to use this instruction :

typedef struct set_t s;

so as to avoid the looping problem.

But this time I have another problem/warning, which I think I understand: when I do something like (let's assume we have a node_t* n):

    set_t* s = (set_t*)malloc(sizeof(set_t));
    n->set= s;

I have a assignement from incompatible pointer type warning, maybe because s is a set_t* but n->set is a s* ...

What am I doing wrong ? I really want to understand how this works when you want to include x.h in y.h and y.h in x.h ... Same thing if y.h needs x.h, z.h needs y.h, and x.h needs z.h .. I really hope I'm clear enough for you guys to help me.

alk
  • 69,737
  • 10
  • 105
  • 255
  • 3
    http://stackoverflow.com/questions/888386/resolve-circular-typedef-dependency. don't cast malloc return. `void *` do the job. don't typedef a struct twice. do it only in one header. – Stargateur Dec 03 '16 at 10:47

1 Answers1

1

The compiler takes the type s as being something different then the type set_t.

To align this do the following:

In set.h change

typedef struct {
  list_t * list;
} set_t;

to be

typedef struct Set {
  list_t* list;
} set_t;

In node.h change

typedef struct set_t s;

to be

typedef struct Set set_t;  // True forward declaration of set_t.

and

  s * set;

to be

  set_t * set;

Update:

Dropping all those useless typedef perhaps makes things clearer. Your code would then look like this:

set.h

#ifndef _SETH_
#define _SETH_ 

#include "node.h"
#include "list.h"

// define type "struct Set"
struct Set {
    struct List * list; // defintion of struct List to be adjusted in list.h
};

struct Set * createSet(struct Node*);
struct Set * findSet(struct Node*);
struct Set * unionSet(struct Node*, struct Node*);


#endif

node.h

#ifndef _NODEH_    
#define _NODEH_

// declare forward type "struct Set"
struct Set;

// define type "struct Node"
struct Node {
    int color;
    int dist;
    int key;
    int date;
    int end;
    struct Set * set;
    struct Node* father;
};

struct Node * createNode(int);


#endif
alk
  • 69,737
  • 10
  • 105
  • 255
  • Thank you very much for your time, I have one more question if you have more time for me, what are we doing exactly? Are we renaming the structure or something? When we do typedef struct Set { list_t* list; } set_t; What is "Set"? and what is "set_t" ?? – Monsieur Ourer Dec 03 '16 at 13:46
  • 1
    `struct Set` is a *named* struct data type. Using the `typedef` you just create another type in another name space for the same thing. In fact you complicate things, and as usual when complicating things increase the possibility of misunderstandings, which one of such you faced. @MonsieurOurer – alk Dec 03 '16 at 14:09
  • ok, it's clearer for me now, thank you very much for your help :) – Monsieur Ourer Dec 03 '16 at 16:30