Should I put the includes in the header file or the source file? If the header file contains the include statements, then if I include that header file in my source, then will my source file have all of the included files that were in my header? Or should I just include them in my source file only?
Your source file will have the include statements if your put it in the header. However, in some cases it would be better to put them in the source file.
Remember that if you include that header in any other sources, they will also get the includes from the header, and that is not always desirable. You should only include stuff where it is used.
If header file A #includes
header files B and C, then every source file that #includes
A will also get B and C #included
. The pre-processor literally just performs text substitution: anywhere it finds text that says #include <foo.h>
it replaces it with the text of foo.h
file.
There are different opinions on whether you should put #includes
in headers or source files. Personally, I prefer to put all #includes
in source file by default, but any header files that cannot compile without other pre-requisite headers should #include
those headers themselves.
And every header file should contain an include guard to prevent it being included multiple times.
Only put includes in a header if the header itself needs them.
Examples:
- Your function returns type
size_t
. Then#include <stddef.h>
in the header file. - Your function uses
strlen
. Then#include <string.h>
in the source file.
Your #include
s should be of header files, and each file (source or header) should #include
the header files it needs. Header files should #include
the minimum header files necessary, and source files should also, though it's not as important for source files.
The source file will have the headers it #include
s, and the headers they #include
, and so on up to the maximum nesting depth. This is why you don't want superfluous #include
s in header files: they can cause a source file to include a lot of header files it may not need, slowing compilation.
This means that it's entirely possible that header files might be included twice, and that can be a problem. The traditional method is to put "include guards" in header files, such as this for file foo.h:
#ifndef INCLUDE_FOO_H
#define INCLUDE_FOO_H
/* everything in header goes here */
#endif
There's been quite a bit of disagreement about this over the years. At one time, it was traditional that a header only declare what was in whatever module it was related to, so many headers had specific requirements that you #include
a certain set of headers (in a specific order). Some extremely traditional C programmers still follow this model (religiously, in at least some cases).
More recently, there's a movement toward making most headers standalone. If that header requires something else, the header itself handles that, ensuring that whatever it needs is included (in the correct order, if there are ordering issues). Personally, I prefer this -- especially when the order of headers can be important, it solves the problem once, instead of requiring everybody who uses it to solve the problem yet again.
Note that most headers should only contain declarations. This means adding an unnecessary header shouldn't (normally) have any effect on your final executable. The worst that happens is that it slows compilation a bit.
You should only include files in your header that you need to declare constants and function declarations. Technically, these includes will also be included in your source file, but for clarity sake, you should only include in each file the files you actually need to use. You should also protect them in your header from multiple inclusion thusly:
#ifndef NAME_OF_HEADER_H
#define NAME_OF_HEADER_H
...definition of header file...
#endif
This prevents the header from being included multiple times, resulting in a compiler error.
Make all of your files so that they can be built using only what they include. If you don't need an include in your header remove it. In a big project if you don't maintain this discipline you leave yourself open to breaking an entire build when someone removes an include from a header file that is being used by a consumer of that file and not even by the header.
The approach I have evolved into over twenty years is this;
Consider a library.
There are multiple C files, one internal H file and one external H file. The C files include the internal H file. The internal H file includes the external H file.
You see that from the compilers POV, as it compiles a C file, there is a hierarchy;
external -> internal -> C code
This is the correct ordering, since that which is external is everything a third party needs to use the library. That which is internal is required to compile the C code.
In some environments, compilation will be fastest if one only includes the header files one needs. In other environments, compilation will be optimized if all source files can use the same primary collection of headers (some files may have additional headers beyond the common subset). Ideally, headers should be constructed so multiple #include operations will have no effect. It may be good to surround #include statements with checks for the file-to-be-included's include-guard, though that creates a dependency upon the format of that guard. Further, depending upon a system's file caching behavior, an unnecessary #include whose target ends up being completely #ifdef'ed away may not take long.
Another thing to consider is that if a function takes a pointer to a struct, one can write the prototype as
void foo(struct BAR_s *bar);
without a definition for BAR_s having to be in scope. A very handy approach for avoiding unnecessary includes.
PS--in many of my projects, there will be a file which it's expected that every module will #include, containing things like typedefs for integer sizes and a few common structures and unions [e.g.
typedef union { unsigned long l; unsigned short lw[2]; unsigned char lb[4]; } U_QUAD;
(Yes, I know I'd be in trouble if I moved to a big-endian architecture, but since my compiler doesn't allow anonymous structs in unions, using named identifiers for the bytes within the union would require that they be accessed as theUnion.b.b1 etc. which seems rather annoying.