I'm working with an embedded system, and I'm ending up with a ton of HW-interfacing #define functions. I want to put all of these into a separate file (for OOP-ness), but I don't know the best way to #include that. Do I just put them all into a .c file, then include that? Seems silly to put these in a .h file.
These should go in the .h
files. The other option is a .c
file, and that would require using #include
to include a .c
file, which will very definitely confuse people -- as well as confusing your makefile, if it uses the standard assumption that every .c
file will correspond directly to a compiled .o
file.
The normal pattern is that .h
files are for things that are included in other places (and, particularly, in multiple other places), and that .c
files are for things that are compiled once into object files.
Thus, the following things normally go into .h
files:
- Function prototypes
- Constant declarations
- Global variable
extern
declarations - Inline function definitions
- Type definitions
- and macro definitions, such as what you're asking about.
Conversely, the following things normally go into .c
files:
- Global variable definitions
- Function definitions that will be compiled into object code and linked
The case of "function definitions only go into .c
files" is simply the degenerate case when you don't have any inline functions.
In C++, where lots of functions are defined in templated form and thus the definitions need to be included whenever they're used, those definitions very often go in the .h
(or .hpp
, or whatever) file. So this sort of thing definitely has precedent.
I'm not necessarily recommending this but have seen it in quite a few embedded projects over the last 10+ years: include inline functions as .inl.
Brooks breaks down the responsibilities nicely. You might consider separating inline and macro definitions from ordinary function prototypes and such:
#include "prototypes.h"
#include "macros.inl"
int foo(void);
int bar(char);
Your end goal is consistency: any layout decisions should assist those who succeed you.
Put them where you need them.
If you need it only for one file then put it at the top of that file.
If you need it for multiple files then put it in a header file.