C header file #ifndef #include error - c

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.

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

Just drop the line
#include "headerB.h"
from file headerA.h

Related

C circular dependency with headers

I am working on a project where I have to follow guidelines on the organization of the files and I can't get it to compile.
To simplify it I have a main.h where I HAVE to define bool and some symbols to go along with it:
#ifndef main_h
#define main_h
#include <stdio.h>
#include "test.h"
typedef unsigned char bool;
#define TRUE 1
#define FALSE 0
#endif /* main_h */
Then the main.c HAS to use a type "num_seconds_t" and a function "test()", both of which have to be in a seperate file from main.
so I have my test.h:
#ifndef test_h
#define test_h
#include <stdio.h>
#include "main.h"
typedef int32_t num_seconds_t;
bool test(num_seconds_t var);
#endif /* test_h */
and my test.c:
#include "test.h"
bool test(num_seconds_t var){
num_seconds_t test = var;
return TRUE;
}
I don't think main.c would have any affect on this issue.
The error states unknown type "bool" in my test.h file, and I kind of understand why as when it hits the include for "test.h" within the main.h it starts going through that file before it has defined bool in main.h, then since main.h has "#ifndef main_h" when it hits "#include "main.h"" in the test.h it skips this and continues reading so bool never gets defined until after the test.h is done being read.
I am not sure if my understanding is correct, but what is the proper way of solving this. By simply moving the "#include "test.h"" to after the definition of bool it will compile, but in my big project I have many files that intertwine and coordinating the order of including these files would be very tough if not impossible.
Thanks
I'll present 3 solutions:
1) Your best option is to not #include test.h in main.h, since you don't need anything defined in test.h in main.h (you do need stuff from test.h in main.c, so test.h should be #includeed in main.c). This is good practice in general, as described in the comments (you don't want to #include something you don't need).
2) Your second best option is to move things from test.h and main.h to another file. In this case, you'd want to move your typedefs and #defines to another file like so:
typedef unsigned char bool;
#define TRUE 1
#define FALSE 0
typedef int32_t num_seconds_t;
and then include this file in main.h and test.h (or just in test.h because `main.h doesn't need these typedefs).
3) Your last and worst option is to carefully choose the order in which you include things. This is your worst option, since it gets very unwieldy with a large project, but I will show it nonetheless.
Leaving all your other files the same and doing:
// main.c
#include test.h
as the only include in main.c will solve your problem. When you try to compile this, only test.h will be #includeed in main.c. This will then include main.h, which has the typedefs you need for test.h. main.h won't include test.h again, since it has already been included. This is okay, because main.h doesn't actually need test.h.
You could also move your #include in main.h below your typedefs and include main.h in main.c. As I mentioned, however, option 3 is not a good option.
You should really do some combination of options 1 and 2 (in general, not just for this project).

Is it possible create a "variable" header guard name in C?

fellow programmers,
I'm new to the C preprocessor and have been recently trying to create a generic-like library in C (as an exercise), and I've come upon a little problem when creating header guards.
All the preprocessor macros are set up so I can include and use my headers like this:
#define TYPE int
#include "myheader.h"
#undef TYPE
#define TYPE float
#include "myheader.h"
#undef TYPE
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
But the problem appears when I need to include the headers in more than one file. Header guards are usually applied in this case, but since the header can be included once -for each type-, neither the usual construction nor #pragma once can be used.
My question then is: Is it possible to create a "variable" header guard to work for different TYPE definitions?
When you want to include the header from various compilation units, you could divide the header into a publich part that plays the role of the header and a private part that plays the role of a *.c file, for example:
#define M_CONCAT(a, b) a##b
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b);
#ifdef IMPLEMENT
TYPE M_CONCAT(TYPE, _min)(TYPE a, TYPE b)
{
return (a < b) ? a : b;
}
#endif /* IMPLEMENT */
Then you can include this header from multiple files, but you have to make sure that only one file defines IMPLEMENT before including the header:
#define IMPLEMENT // only in one file
#define TYPE float
#include "myheader.h"
#undef TYPE
#define TYPE int
#include "myheader.h"
#undef TYPE
This file could be a separate compilation unit, myheader.c. You must take care to implement the function for all types, however. (But the linker will tell you, which types you've missed.)
I suggest:
Remove the #include guards in myheader.h.
Create different header files for each TYPE.
intheader.h:
#pragma once
#define TYPE int
#include "myheader.h"
#undef TYPE
floatheader.h:
#pragma once
#define TYPE float
#include "myheader.h"
#undef TYPE
And then use:
#include "intheader.h"
#include "floatheader.h"
int main(void){
//Do stuff
MyFunc_int();
//More stuff
MyFunc_float();
return 0;
}
I think you're looking for something like this:
#if !defined HEADERGUARD && defined (TYPE==int)
#define HEADERGUARD
<stuff>
#endif
You may want to have HEADERGUARD_int and HEADERGUARD_float, depending on what you're doing inside the *.h file. More conventionally, people will break it into two *.h files.

C Unknown type name 'my_structure'

I have this code:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
and
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
but I'm getting this when I try to compile: error: unknown type name ‘my_structure’
Any idea why?
Because of how you've ordered your includes, the compiler sees void some_func(my_structure *x); before it sees typedef struct abcd { int a; } my_structure;.
Let's walk this through.
Assuming my_struct.h is processed first, we get the following sequence of events:
UTILSH is defined
MAINH is defined
Because UTILSH is already defined, we don't process my_struct.h again, so the typedef isn't processed
void some_func(my_structure *x); is processed.
Now the typedef is processed.
So after preprocessing, your compiler sees the following sequence of declarations:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
Bad juju. You either need a forward declaration of my_structure in main.h, or you need to break that circular dependency (which is the much preferred option). Is there anything in main.h that my_structure.h actually uses? If so, you will want to factor it out into a separate file that both main.h and my_structure.h include.
You created a circular header inclusion. Circular inclusion never achieves anything. It is infinite. The #ifndef include guard will break the infinite inclusion circle at some unpredictable point (depending on which header is included into .c file first). This is what happened in your case. Basically, your circular inclusion got "resolved" into including main.h first and my_struct.h second. This is why main.h knows nothing about my_struct type.
Again, circular inclusion never achieves anything. Get rid of circular inclusion. Design your header structure hierarchically: lower-level headers included into higher-level headers, but never the other way around. In your case my_struct.h is probably a lower-level header, which means that you have to stop including main.h into my_struct.h. Redesign your headers so that my_struct.h no longer needs main.h.
The error message is coming from main.h while it's included in my_struct.h, before my_structure is defined. You should rethink your include paths since main.h and my_struct.h include each other.
You probably want your main.h file to just include my_struct.h, and not have my_struct.h to include anything. You're essentially instructing your C compiler to have an infinite co-include loop.

C - #include and multiple typedefs

I'm writing an embedded C program in eclipse with gcc and can't see how to get around a certain issue. I have a typedef in a header file which is protected by an include guard. Since I use this typedef in multiple headers, I need to include it in other headers, however when I try to compile, no matter what I do, one of the headers cannot see the typedef and complains of an unknown type name.
I believe this illustrates the problem:
header a.h:
#ifndef _a_h
#define _a_h
typedef enum {
USBD_OK = 0,
USBD_BUSY,
USBD_FAIL,
}USBD_Status;
#endif
header b.h:
#ifndef _b_h
#define _b_h
#include "a.h"
extern USBD_Status USB_getStatus(void);
#endif
header c.h:
#ifndef _c_h
#define _c_h
#include "a.h"
extern USBD_Status USBD_Sync(void);
#endif
This always seems to result in the error "unknown type name 'USBD_Status'" as whichever header is compiled second cannot see the typedef. Removing the include guard from a.h results in the complaint that USBD_Status is being redeclared.
edit:
I have double checked all include paths, all includes, all file names and all include guards - there are no duplicates or typos.
It could be that you have another header that uses the same header guard name.
You could add some code to the top of your a.h that does this:
#ifdef _a_h_
#error this header is already defined
#endif
This way you can track down everywhere that a.h is included and see where any oddities may occur.
As stated in the comments, your above example works so the problem must lie somewhere else ...

How does inclusion of header file happen?

I have a plain C code with *.c and *.h files in the workspace.
I have a header file 1.h declaring some structure as
struct my1
{
int a;
..
..
}my_t;
But when i try to declare a variable of type struct my1 in another header file 2.h as follows:-
struct my1 variable1;
It gives error at this declaration point.
Looks like my1 is undefined here in 2.h file.
In file 1.h I need to include 2.h, so in file 2.h I cannot include 1.h, for fear of recursive inclusion.
My question is:-
What do i need to declare to resolve the compilation error in this case?
This whole thing made me think about further questions about header file inclusions.
How are the header files included, in what order, which header file first then which one?
Will recursive inclusion of header files cause errors one file including other and other including first?
Could not post the actual code snippets for some security reason, so sorry if the question somewhat poses some readability problems.
You should start by putting an inclusion lock in all your .h files (this is called an include guard):
#ifndef ONE_H
#define ONE_H
//rest of header
#endif //ONE_H
That way you can include it multiple times.
Second:
typedef struct my1 { int a; .. .. }my_t;
You need a typedef in C (not in C++)
The headers are included in the order of inclusion.
If you compile a file abc.c which starts with:
#include "a.h"
#include "b.h"
then a.h will be included first, then b.h.
You could think of it, as if you paste the code in the file. It is included at that point.
It's like the folks said before.
I just want to add that sometimes even #ifdef won't help you.
//file1.h
#ifndef F1
#define F1
#include "file2.h"
struct file1st {
struct file2st *ptr;
};
#endif
//file2.h
#ifndef F2
#define F2
#include "file1.h"
struct file2st {
struct file1st *ptr;
};
#endif
//main.c
#include "file1.h"
#include "file2.h"
/*
This will give you an error of **struct file1st not defined**
Let's see why:
1) file1.h is included
2) file1.h includes file2.h before it declares anything
3) the definition of struct file2st occurs and it uses struct file1st which isn't declared yet
*/
int main(int argc, char* argv[]){
struct file1st st1;
struct file2st st2;
return 0;
}
The way to work this out is:
//file1.h
#ifndef F1
#define F1
struct file2st;//just declare, it will be defined later.
struct file1st {
struct file2st *ptr; // ok, compiler KNOWS the size of struct file2st*(pointer)
struct file2st file2Var;// NOT ok, compiler doesn't know sizeof(struct file2st)
};
#endif
//file2.h
#ifndef F2
#define F2
#include "file1.h"
struct file2st {
struct file1st *ptr;
};
#endif
Header files are included in the order of include directives. Once the compiler sees an include directive it opens the file to include and simply inserts all of its contents into the including file.
If the included file has include directives inside, the same is done for them. This process continues until all of the include directives have been processed.
Only after that the compilation is started.
That's why if any file is included more than once (A included B and C; both B and C include D for example) you'll often see compiler complaining about redefinitons. To resolve this add inclusion locks (aka include guards) - the ifdef directives.
//file Header1
#ifndef Header1Guard
#define Header1Guard
// all the header text here
#endif
I second the guard suggestion.
I religiously use the following header template:
#ifndef HELLOWORLD_H_
#define HELLOWORLD_H_
// Header stuff here.
#endif // HELLOWORLD_H_
When the compiler see's an #include, it simply replaces that line with the contents of the header file (minus any processed directives in the header). So, that means you can include the file in as many places as you like without risking recursive includes.
Every header file is included in every translation unit (source file) in which there is an include directive for it. This is intended, and will happen even with inclusion guards -- every translation unit that uses your struct needs to know how that struct is defined so that it can be laid out in memory the same way throughout all the translation units of your app. The inclusion guards just prevent it from being included multiple times within one translation unit. Include files will be included in the order you include them within that translation unit (and they'll be recursively included if include files include other files... as others have said). The order of translation units being compiled is up to you (or your IDE) to specify to the compiler. It shouldn't matter what that order is, however, since every translation unit is completely independent until it gets to the linking phase of the build process.
It's been a while since I worked with C, but I think what you want to do is forward define my1.
In 2.h, try putting this near the top:
struct my1;
Sorry, I can't answer your other two questions.
// Header1.h
typedef struct tagHeader1
{
} Header1;
// Header2.h
struct Header1;
// Header2.c
#include "Header1.h"
Note: This only works for pointers (and in c++, references). If you have a reference to a complete object, the compiler will need to know about it.

Resources