4

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,122
  • 7
  • 34
  • 43

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,440
  • 1
  • 26
  • 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
  • 34,346
  • 23
  • 113
  • 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
  • 378,987
  • 63
  • 458
  • 590
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
  • 106,562
  • 103
  • 351
  • 513