Assume I have a module filter.c/filter.h.
That module exposes a function in the header:
uint32_t filterStuff(uint32_t input);
This means I need to include stdint.h, and I need it in both the filter.c AND the filter.h
In the past I simply included stdint.h in filter.h. Since filter.h is also included inside filter.c the code has the int32 typedef available as well and everything works.
But when I check that code with clang-tidy I get a
no header providing "uint32_t" is directly included
warning from misc-include-cleaner.
Does this suggest I should include stdint.h in both filter.c AND filter.h separately? Is that considered good style?
NOTE: I'm asking only about the case where something is included in the header directly belonging to some c-file: foo.c and foo.h. I'm not asking about trusting correct indirect includes from headers NOT directly belonging to said module.
The header filter.h
should include <stdint.h>
since one of the functions it declares needs one of the types from <stdint.h>
, and a header should be self-contained, minimal and idempotent. (For more discussion, see Should I use #include
in headers? and other questions.)
The code in filter.c
necessarily uses filter.h
, so it does not really need to include <stdint.h>
directly. However, other source files might use filter.h
for some parts of the code but also use types from <stdint.h>
separately from the use mandated by filter.h
. It becomes contentious whether those other files should include <stdint.h>
directly. The argument in favour of doing so is that if the code ceases to need filter.h
, then the <stdint.h>
header will need to be added to the source to provide the now-missing declarations. The argument against that is "the code will have to be changed when it stops using filter.h
, and adding the <stdint.h>
header would simply be one of the other necessary changes".
I tend towards the "against" view — I would not include <stdint.h>
. But I'm not 100% consistent about it (is anyone 100% consistent?). If the policy is to use tools that complain if you don't include the file directly, then follow the rules imposed by that policy and the tools you use.
I still regard self-containment as important. If I include a header x.h
, I should not need to include other headers y.h
and z.h
(that I may not even be fully cognizant of) in order to use the facilities of x.h
.