I try to adhere to the following rules with respect to C headers and includes
0) each .h/.c file set is a C "unit"
1) the header file is the "public interface" of the unit
2) it includes prototypes of all functions to be called from outside
3) it does not define any data (e.g. int x;)
3a) this dovetails with the OO principle: for me all data is owned by a unit, no data is shared, if you want to access data in another unit write get/set functions
4) due to (3) a header file can be included more than one time in an application, from any other unit that needs to access it
5) each unit only #includes the other files whose functions it needs to call
This has been a great approach, worked well, minimizes and provides clear indication of the dependencies, kept me out of "include hell", trying to resolve circular dependencies (since it is no problem two units #include-ing each other's headers) or those dumb-seeming long #include lists that big (maybe sloppy?) C applications seem to use.
This has been such a good approach that I wonder if I'm finally doing it as intended, that (1) through (5) is exactly what the C designers had in mind.
But a problem I'm encountering is with enums. Whereas I can #include a header file with only function declarations multiple times, if it has an enum definition I get a redefinition error. But I would really like the enum to be part of the public interface; a get_mode function could return a value of one of several mode enumerations, for example.
If I have stumbled upon the "right" way to do this, then is there a way to use enums in the public interface consistent with my rules (1) - (5).
(I know I could use #define "guards" at the beginning and end of the header files to prevent them from being re-included, but I'd prefer not to if I can help it.)
Thanks for any thoughts.