Home > database >  Header files recursion in C
Header files recursion in C

Time:08-04

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 typedefs 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.

  • Related