Search code examples
cembeddedheader-filessoftware-design

Using #include in header files


Assuming we have 2 files DIO.c and DIO.h. I used to #include all necessary header files in DIO.h and only #include DIO.h in DIO.c. while working on drivers for ATmega32, I found out that some functions are declared implicitly while including other modules. This made me wonder is that right to include all files in header file instead of source file? and how what i'm doing currently affects dependency?

After visiting some repos on github i found out that they never #include anything in header files, and only include everything in C file, which made me more confused about what about typedefs? how they use them without including the header file containing them?

Here is an example of DIO.h file:

#include "Dio_Private.h"
#include "Dio_Config.h"
#include "../../Utilities/Macros.h"

and here is an example of DIO.c file:

#include "DIO.h"

If the answer was that I should include all header files in C file, what about enums?

for example, if I want to use enums defined in DIO.h file in any other module, should I now seperate these enums in another header file and only #include it?

Thanks in advance :)


Solution

  • This question is a matter of opinion and style, and therefore probably not regarded as a "good" question for SO. I can offer advice only:

    • Include anything in the header file necessary to make the header file valid without requiring additional includes.

    So for example if header file xxx.h references a symbol such as int32_t, then it should explicitly include stdint.h. Otherwise the user of the header file will have to "know" that stdint.h is required to be included before xxx.h, even if the subsequent source never references stdint.h type or symbols.

    To not allow nested includes is a nonsense, because the user of a header file will have to know or work out what include dependencies are required and they cold be very many.

    On the other hand to include headers for symbols not referenced in the header itself pulls in interfaces the user might not expect and is inefficient. You might do that when a public interface is a collation or parts in multiple headers, but you need ot be able to justify it and follow the principles of maximum cohesion, minimal coupling.

    After visiting some repos on github ...

    I would not assume some randomly selected repo to be definitive or even good practice or the arbiter of such. Being published on Github is not an indication of quality - it is a poor strategy to learning good coding style. You might better take your "best-practice" cues from standard or device library headers for example.