I have this situation:
A.h and B.h
In A.h:
typedef struct TypeA TypeA_t;
struct TypeA {
...
TypeA_t *a;
void (*doSomething)(TypeB_t *);
};
In B.h:
typedef struct TypeB TypeB_t;
struct TypeB {
...
TypeB_t *b;
TypeA_t something;
};
What is the correct way to include header files in each file?
If I include A.h
in B.h
and B.h
in A.h
I get:
error: unknown type name 'TypeB_t'
in A.h
and
error: unknown type name 'TypeA_t'
in B.h
I found a similar question here but it doesn't work in my case.
CodePudding user response:
The way you've defined your code, TypeA
can live with a forward reference to TypeB
, but TypeB
needs the full declaration of TypeA
to compile.
In other words, you need to do two things. First forward define TypeB
in a.h
before your class definition (because pointers can work with partial definitions):
//a.h
typedef struct TypeB TypeB_t;
typedef struct TypeA TypeA_t;
struct TypeA {
...
TypeA_t *a;
void (*doSomething)(TypeB_t*);
};
And then include a.h
from b.h
to get the declaration for your class (because you use the full TypeA
class as a field type):
// b.h
#include "a.h"
typedef struct TypeB TypeB_t;
struct TypeB {
...
TypeB_t *b;
TypeA_t something;
};
CodePudding user response:
The typedef
s can be moved to other header files, and use header guard macros to prevent multiple definitions:
At.h
#ifndef AT_H_INCLUDED_
#define AT_H_INCLUDED_
typedef struct TypeA TypeA_t;
#endif
Bt.h
#ifndef BT_H_INCLUDED_
#define BT_H_INCLUDED_
typedef struct TypeB TypeB_t;
#endif
A.h
#ifndef A_H_INCLUDED_
#define A_H_INCLUDED_
#include "At.h"
#include "Bt.h"
struct TypeA {
TypeA_t *a;
void (*doSomething)(TypeB_t *);
};
#endif
B.h
#ifndef B_H_INCLUDED_
#define B_H_INCLUDED_
#include "Bt.h"
#include "A.h"
struct TypeB {
TypeB_t *b;
TypeA_t something;
};
#endif
.c files shouldn't need to include "At.h" or "Bt.h". The inclusion of "At.h" and "Bt.h" can be policy restricted to be included only by the main header files. Including "A.h" will fully define TypeA_t
. Including "B.h" will fully define TypeB_t
(and will also fully define TypeA_t
). They can be included in any order.