What is this obsession with replying 'Don't forget the inclusion guard'???
It's old hat. My secnario has this in place.
My problem is one module is creating a dependancy on another module only
because the first module wants to use one single #define in the second
module.
The application is a large one, backed up by an overly sophisticated build
system, which would mean if I want to pick up module 2, I pick up all of it:
it all gets compiled. (And yes, I know: it won't get linked in!).
So the question is: is it normal practise to create intermodule dependancies
for trivial reasons?
In my opinion, a source file containing two single lines must compile
without diagnostics, or with only a diagnostic concerning the failure
of the translation unit to contain any external declarations:
#include "required_project_header.h"
#include "header_in_question.h"
....where "required_project_header.h" is just that, required to be the
first header included in every C source file in the project. It in
turn includes at least <stdint.h> and <stddef.h>, plus generally some
project-specific headers with universally used typedef's and macros.
In setting up the rules for our latest large C embedded project, I
tried to eliminate some of the more obvious disadvantages of earlier
project structures. The biggest of these was "header dependency
hell".
In earlier projects, functions and data types that provided interfaces
between various modules of the program were all placed in a single
header for each module, named xxx_api.h for module xxx.
The problem is that xxx_api.h almost always needed to include some
type defined by a different module in some structure of its own, or
accept or return one (or a pointer to one) in a function call.
So xxx_api.h required the inclusion of yyy_api.h, which in turn needed
something from zzz_api.h, and in the end way too many files ended up
including most or all of the API headers.
The obvious solution, which has reduced these dependencies greatly, is
to require two headers for things exported by each module:
xxx_api_types.h
xxx_api_calls.h
The latter, of course, must include the former. A few simple rules:
1. C source files may only include *_calls.h files, and never any
*_types.h, other than that belonging to its own module.
2. *.api_calls.h files must include their own api_types.h file, and
may include other *api_types.h files, but may not include any other
api_calls.h files.
This has cut the header coupling down significantly.
If you are working with legacy code, and can't completely reorganize
the code base, consider moving the one dependency to a header file of
its own:
some_header_name.h:
#ifndef THIS_IS_DEFINED_IN_HEADER2
#define THIS_IS_DEFINED_IN_HEADER2 5
#endif
Include this header in the big include file in place of the
definition, and include it in other places that only needed this
symbol from the big include file.
This is the sort of thing that is a good candidate for inclusion in
"required_project_header.h".