5

Suppose you have to related structures defined in 2 header files like below:

a.h contents:

#include b.h

typedef struct A
{
  B *b;
} A;

b.h contents:

#include a.h

typedef struct B
{
  A *a;
} B;

In such this case, this recursive inclusion is a problem, but 2 structures must point to other structure, how to accomplish this?

whoi
  • 3,281
  • 7
  • 36
  • 44

4 Answers4

5

Don't #include a.h and b.h, just forward-declare A and B.

a.h:

struct B; //forward declaration
typedef struct A
{
    struct B * b;
} A;

b.h:

struct A; //forward declaration
typedef struct B
{
    struct A * a;
} B;

You might want to think about how tightly coupled the classes are. If they're very tightly coupled, then maybe they belong in the same header.

Note: you'll need to #include both a.h and b.h in the .c files to do things like a->b->a.

Doug
  • 8,780
  • 2
  • 27
  • 37
3

Google C/C++ guidelines suggests:

Don't use an #include when a forward declaration would suffice

That'd mean:

a.h contents:

typedef struct B B;

typedef struct A
{
  B *b;
} A;

b.h contents:

typedef struct A A;

typedef struct B
{
  A *a;
} B;

If you prefer something a bit safer (but longer to compile) you can do this:

a.h contents:

#pragma once
typedef struct A A;

#include "B.h"

typedef struct A
{
  B *b;
} A;

b.h contents:

#pragma once
typedef struct B B;

#include "A.h"

typedef struct B
{
  A *a;
} B;
Wernight
  • 36,122
  • 25
  • 118
  • 131
  • Just for my curiosity, what is `#pragma once`? – Jens Gustedt Sep 22 '10 at 12:25
  • It's the new way (supported by pretty much any compiler) of doing `#ifndef MY_HEADER_H__ #define MY_HEADER_H__ ... #endif`. It means that if you have #include "foo.h" twice and foo.h has `#pragam once`, it'll only apply the declarations once. Else you'd have a compilation error. – Wernight Sep 22 '10 at 12:29
2

You pre-define the struct only, in that way you can still declare a pointer:

In a.h:

typedef struct B_ B;

typedef struct A_
{
  B *b;
} A;

Note how I use separate names for the typedef and struct tags, to make it a bit clearer.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

This will cut it in C:

typedef struct B B;
typedef struct A A;
struct A { B *b; };
struct B { A *a; };

You can rearrange B and A as desired.

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526