Is there any reason not to write one header file that #includes all other header files and just #include that one header in each c file?
Each header file is setup #ifndef ... #define ... #endif
To clarify the duplicates; I was asking about user written code not system headers and the other possible duplicate didn't have answers that specified why it wasn't a good idea.
Thanks for the answers, I hadn't thought through some of them. I will look a taking the hybrid approach of some smaller headers for modules that fit together. This is for a codebase that I have taken over, it's very much a web I'm slowly trying to untangle.
答案 0 :(得分:3)
The reason we split up header files and implementation files into separate files in the first place (aside from code readability) is to enable incremental building by the compiler. That is, if we make a change in HeadearA.h
that only ImplA.c
and ImplB.c
need, there is no need to recompile ImplC.c
through ImplZ.c
. If you do it your way, however, there is no way for the compiler to know that, and you will wind up recompiling all of the .c
files for every rebuild, regardless of necessity. For small projects with small build times, this is okay. For larger projects that have build times nearing 30 minutes, this becomes prohibitive.
答案 1 :(得分:2)
What you suggest is possible: many projects use this convention.
Some advantages:
Some drawbacks:
答案 2 :(得分:2)
For a non-trivial project, a combination of both policies is often used: One header which includes commonly used system headers like stdbool.h
, stdint.h
, stdatomic.h
, etc. As these never change, they are note relevant for rebuild.
You also might include some project-settings which are required by most/all modules, so you don't have to care about them when writing a new module (or change every module when refactoring them).
And then you have specific headers which represent your module-dependency tree. These are included as required. This not only speeds up building (not compiling) the project, but also can be used by doc-tools like doxygen
to automatically create the dependency tree for the documentation, so you don't have to track every change manually. A similar approach may be used by an IDE for quick access to dependant headers/modules.
One disadvantage which expecially appies to C is called namespace pollution. As C does not allow for custom namespaces, every included header will have its symbols added to the namespace of the current compilation unit. For Macros, this might be even worse, as they are plain text-replacements with very limited knowledge of the context (for this, also check inline
vs.
function-macro).
答案 3 :(得分:2)
The main problem is that you end up with a big bowl of spaghetti code and everything knows about everything ..eventually .anything you change has repercussions, and you end up having to refactor to re-modularize... You don't have the tiny little reminder of actually including some header to make the decision of x should know about y.
But there isn't anything intrinsically wrong with it aside from the normal issues of symbol visibility and macro expansion, which should be edge cases..