Guinn
Guinn

Reputation: 1385

Should I, or should I not include the same headers in different c files, which in turn are headers used in a main file?

I'm building a main.c file to make use of functions out of a few different .h files. A few of those .h files (or rather, their .c source files) use the same includes (the standard but also some others like )

My question is: Is it okay if I just include those once for all header files in my main.c, or should I let every .h file include them individually and not include them in my main.c (considering I only use functions from those header files)?

Or should I do both?

How I do it now is:

dist.c:

#include "dist.h"
#include  <stdio.h>
#include  <unistd.h>
#include  "rpiGpio.h"
#include <pthread.h>
#include  <wiringPi.h>
#include  <softPwm.h>

Then for another:

cmps.c:

#include "cmps.h"
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include "rpiGpio.h"

Then in my main.c:

#include    <stdio.h>
#include    <stdlib.h>
#include    "dist.h"
#include    "cmps.h"

Thanks in advance!

Upvotes: 7

Views: 2243

Answers (2)

abligh
abligh

Reputation: 25129

I think the answer is "it depends". So long as you are consistent, I think it's OK. Some advantages and disadvantages of different approaches:

  1. Including a system header twice will not cause adverse effects (due to header guards); including your own headers twice should also not cause problems provided you use header guards too. However, arguably it may slow compilation.

  2. In some circumstances, particularly on older Unices, the order of inclusion of headers matters (sadly). Sometimes the order of #defines (e.g. #define _GNU_SOURCE) does matter with respect to #include. I've also had this happen with Linux include files for various internal bits of networking (I now forget what). For this reason, it's a good idea to always include your system includes (and the #defines they examine) in a consistent manner.

  3. One way to do that is to put all your system includes in a single include file of your own, and include them from each .c file; this produces much the same result as you would get with autoconf and its generated config.h. However, it may unnecessarily include files slowing compilation down.

  4. Some say put includes of system headers above your own includes. Whilst this is often seen as good practice, it doesn't work great if your own .h files reference types defined in system includes, e.g. stdint.h defines int32_t. If you include that in your .h file alone, you are back to a potential problem with include order and whether or not you've got your #define _GNU_SOURCE in the right place.

  5. Therefore my personal coding style is to have a config.h equivalent, which is included by all .h files and (for good measure) all .c files as the first include, which contains all the relevant system includes. It's not ideal for compile time, but that's what precompiled headers are for. I normally arrange system includes in alphabetical order, unless there is a reason not to.

  6. The alternative is to (carefully) do it by file, as @meagar suggests.

Upvotes: 2

user229044
user229044

Reputation: 239382

You should include standard headers above your own headers, and you should include all the dependencies for a file in that file. If you change the includes in one of your file, it shouldn't affect any other files. Each file should maintain its own list of header dependencies.

If, in your example, dist.h includes <stdio.h>, you should not rely on this outside dist.h. If you change dist.h so that it no longer depends on <stdio.h> and remove that #include, then your program breaks.

Upvotes: 10

Related Questions