I am writing a rather large program in C and I had a question about header files. My main file includes my library header containing all of the function declarations. In the files that contain my function definitions, I have them include that same header file. When I compile, I link all the object files together.
It occurred to me that instead of having my definition files include the header file and then linking the results together, I could simply have the header file include the definitions at the END of the header file, like:
#ifndef HEADER
#def HEADER
#include <stdio.h>
#include <hdf.h>
... (function declarations)
#include "definition1.c"
#include "definition2.c"
#endif
What would be the benefits of doing it this way versus what I have now?
Related
Going over our course material, I noticed that when we #include standard libraries (for example #include <stdio.h>), these #includes appear in the .c file and not in the header file. The #includes that appear in the header file are those that are for local header files, #include "anotherheader.h".
Why is that? It'd make more sense to me that all #include declarations will appear in the header file, and all the .c files will derive them from there.
Whether sources files include standard headers directly or via other included files is a matter of local coding conventions.
It is considered good style to follow these conventions:
include only the necessary headers ;
include standard headers before any other include files and local declarations ;
make every source file compilable as a separate entity, including project header files. This means you should include the standard headers needed for the types used in local header files at the top of these.
protect the definitions in a header file with a header guard: #ifndef SOME_SYMBOL / #endif.
It is good practice to include only what is really necessary in the header file to avoid circular dependencies and to allow for shorter build times.
I have a single main .c file with 4 .h files and .c files included into the main function. Like this:
#include <stdio.h>
#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"
int main(){...}
The .h files have all the declarations for all of their corresponding .c files. Some of the .c files do use functions from other .c files, for example "file4.c" uses some functions declared in "file2.h" and "file1.c" uses functions declared in "file3.h". I've tried declaring the same includes as in main in every .c file and tried reordering the include files, but I still get warning messages about implicit declarations of functions and incompatible implicit declarations.
I was wondering how you would use #includes in your large projects to eliminate warning messages. I'm using gcc as the compiler.
If you want import the .h file in a part of main() file, you must sure that you didn't import it anywhere.
For example:
file4.h use functions in file3.h
If you imported file3.h in file file4.h you have to not import file3.h in file main(). It's the duplicated definition.
If you have a lot of init files. You can import it in the only general file. And use that file in main().
Hope you like it ^^
Try this on all your own head files:
(beginning of your head file)
#ifndef _HEAD_FILE_NAME_H
#define _HEAD_FILE_NAME_H
...
<your headfile contents>
...
#endif
(end of your headfile)
I have a project written in C consisting of FIFO.h, FIFO.c, task.h, task.c and main.c (it's a basic queue).
When I compile my main.c using gcc under Windows it compiles and works just fine. However when I try to compile the exact same code in Eclipse, I get the following error for every function:
One example is:
In function `queue_new':
FIFO\Debug/../src/QueueFIFO.c:20: multiple definition of `queue_new'
src\main.o:FIFO\Debug/../src/QueueFIFO.c:20: first defined here
src\FIFO.o:
I honestly have no idea what additional information you guys could use so just tell me what to do.
main.c includes:
#include "FIFO.h"
#include "FIFO.c"
#include "task.h"
QueueFIFO.c:
#include "task.h"
FIFO.c:
#include "task.h"
#include "QueueFIFO.c"
task.c:
#include "task.h"
You are getting multiple definition errors because you are including your .c files in your .c files. It's the linker's job to make sure they come together. Good practice is to only include .h files in your .c files, and make sure the .h files don't include function definitions (only function prototypes).
By #includeing your .c files, you are defining the functions at least twice: once when FIFO.c is compiled, and again when main.c (which #includes FIFO.c, copying it verbatim into the text before compilation) is compiled. When it comes to link time, the linker sees e.g. queue_new() defined in both FIFO.o and main.o and barfs on the multiple definition of all the functions in FIFO.c.
In addition, as others mentioned, make sure you "guard" your header files to make sure they don't create circular #include dependencies. You can do that with #ifndef and #define as follows:
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include "bar.h"
#include "baz.h"
/* header file contents go here */
#endif /* FOO_H */
This has the effect of only executing the contents of the file once, since FOO_H will be defined if it is included a second time, and the entirety of the file will be skipped over.
I tried compiling with or without the inclusion guards in C headers and made sure that multiple c files includes the same header. It would result to redeclaration and it is allowed. What does it for then?
You prevent circular inclusion:
Example
/** file A.h */
#include "B.h"
/** file B.h */
#include "A.h"
What will happen if you include either "A.h" or "B.h"? Your pre-processor will try to include the other file, which will include the other file, which will include the other file, …
Guards make sure that you won't include the file several times.
Below are two files which I will use as my example. If I define an array of structures in file1.h and have file2.c include file1.h I would get a multiple definition error. Why is that? If I just have struct thread tasks[32] I don't get this error.
file1.h
...
...
struct thread tasks[32] = {0}; // thread is structure defined above
...
...
file2.c
#include file1.h
Most likely you are including the header file in more than one source file. The #include directive literally includes the contents of the header file into the source file, which means that all code in the header file will also be in the source file. This means that if two or more source file includes the same header file then the code in the header file will be duplicated.
The = {0} turns the line from a declaration into a definition. You can have as many (compatible) declarations of a file-scope variable as you like, but at most one definition; by including the header in multiple source files you are causing multiple definitions to be generated.
You can prevent problems from multiple includes by wrapping the contents of your header files in #ifndef like this
/* file1.h */
#ifndef INCLUDE_FILE1
#define INCLUDE_FILE1
/* contents here */
#endif