views:

141

answers:

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?

+2  A: 

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
+1  A: 

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
+3  A: 

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
+1  A: 

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
Just for my curiosity, what is `#pragma once`?
Jens Gustedt
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