4

If a project has a header that includes a second header and both of them include a common header, is it good practice to drop the inclusion of the common header from the first header and rely on the indirect inclusion via the second header?

e.g.: I know the stdint.h can be removed from temperature.h, but should it be?

In temperature.h:

#include <stdint.h>  // *Should* this include be removed in this case.
#include "i2c.h"

extern uint16_t temperatureRead (i2cData_t x); 

In i2c.h:

#include <stdint.h>

typedef struct i2cData_t {
    uint16_t exampleMember
} i2cData_t;
Sam
  • 7,252
  • 16
  • 46
  • 65
Toby
  • 9,696
  • 16
  • 68
  • 132

3 Answers3

5

Generally you want your modules to be self contained. If your module relies on something in a header then include it. Temperature.h may one day decide it doesn't need to include stdint.h any more and have it removed. Your code should have nothing to do with that decision, so safeguard it by including stdint.h, i.e. be self contained.

Use header guards (or C++ pragma once) to make sure your compilation speed doesn't degrade due to including a header multiple times.

Phillip Ngan
  • 15,482
  • 8
  • 63
  • 79
  • @Phllip Ngan - +1 for the great answer, but one question though - Isn't #pragma once supported also in GCC (and perhaps other compilers as well) ? – Guy Avraham Feb 06 '18 at 17:40
  • 1
    @Guy Avrham - you're right. Pragma once is supported for most C++ compilers for a long time. I'll remove the reference to MS C++ from the answer. – Phillip Ngan Feb 10 '18 at 08:21
  • The main purpose of header guards/pragmas is to prevent multiple inclusions of the same file that'll lead to compilation errors. Your last statement makes it seem like they are intended only to improve compilation speeds which they can in some instances but that's definitely not their primary purpose. – Pavan Manjunath Jan 16 '20 at 00:08
3

IMO, no.

Always assume a module is standalone. In above case, temperature.h requires stuffs from both stdint.h and i2c.h so let it be. In case a refactoring happens and i2c.h no longer includes stdint.h, you can avoid compilation problem. It's simple to fix for a small project, but not quite for a big one.

LeleDumbo
  • 9,192
  • 4
  • 24
  • 38
3

I know the stdint.h can be removed from temperature.h, but should it be?

Each source file should include the headers that it explicitly requires. In the posted case, if the type of exampleMember changed to be int and ic2.h no longer includes stdint.h then the compliation of temperature.h fails, even though its source is unchanged. Or, if temperature.h is used by other source files then those other source file must include stdint.h in order for compliation succeed.

hmjd
  • 120,187
  • 20
  • 207
  • 252