Risinek Risinek - 24 days ago 6
C Question

C header file #ifndef #include error

I'm trying to figure out, how to use C headers with #ifndef and #include.
Lets say I have these two header files:

headerA.h:

#ifndef HEADERA_H
#define HEADERA_H

#include "headerB.h"

typedef int MyInt;
TFoo foo;
... some other structures from headerB.h ...

#endif


headerB.h

#ifndef HEADERB_H
#define HEADERB_H

#include "headerA.h"

typedef struct foo{
MyInt x;
} TFoo;

#endif


headerA.c

#include "headerA.h"

... some code ...


headerB.c

#include "headerB.h"

... some code ...


When compiling headerB.c, it says

In file included from headerB.h,
from headerB.c:
headerA.h: error: unknown type name ‘MyInt’


I think, it's becouse when headerB.h is compiling, it defines HEADERB_H and then, when headerA.h wants to include headerB.h, the
#ifndef HEADERA_H
is false = skips including.

What is the best practice here? I just read, that best practice is to do all
#include
directives in header files, but in this situation it looks like a problem.

EDIT: Ok, sorry for misleading you. This is just and example from bigger project with more files.

Answer

You have a circular dependency. Header file headerA.h depends on headerB.h which depends on headerA.h and so on and on.

You need to break that dependency, for example by not including headerB.h in headerA.h. It's not needed (nothing in headerA.h needs anything from headerB.h).


If you have to include headerB.h (as stated in your recent edit) then you first should reconsider how you use your header files, and what definition you place where. Perhaps move the definition of MyInt to headerB.h? Or have more header files, like one for type-aliases (like your MyInt which I personally see no use for), one for structures and one for variable declarations?

If that's not possible then you could try by changing the order of definitions and the include, like

#ifndef HEADERA_H
#define HEADERA_H

// Define type alias first, and other things needed by headerB.h
typedef int MyInt;

// Then include the header file needing the above definitions
#include "headerB.h"

TFoo foo;
... some other structures from headerB.h ...

#endif