First of all, I know how to split a C file into multiple ones.
My question is, is there any advantage other than readability? What is the main reason to split C files?
First of all, I know how to split a C file into multiple ones.
My question is, is there any advantage other than readability? What is the main reason to split C files?
If you split a large C file into several translation units, you practically have to declare the functions involved as (e.g. extern
) in some common included header.
The advantage of splitting is that incremental build time could become slightly smaller. If you change only one statement in one function you just need to compile the file defining that function (and if that file is small, its compilation is fast). However, the compiler needs to parse all the headers. And you may want to define static inline
functions in your header files (and that makes them bigger).
The disadvantage of splitting is that the developer might have harder time to find a given function (but tools like ctags
help) and that the compiler could probably optimize less (e.g. won't inline some function calls, unless you enable link time optimization)
So it is a matter of taste and habit. Personally I like having C or C++ files of more than a thousand lines (and probably less than ten thousand lines), but YMMV. And I dislike projects having one function (of less than a hundred lines) per file (you'll need lots of them in such case). But having one large source file of a hundred thousand lines is generally unreasonable.
I also find source files keeping together related functions more readable (since it is simpler to search a function definition in one file than in many ones).
Notice that header files may expand to something quite big (and it is even more true in modern C++ : a standard header like <vector>
or <map>
may expand to more than ten thousand lines of code), e.g. <stdio.h>
expands to two thousand lines (on my Debian/Linux/x86-64) so having lots of small source files can slow the full build time (since the compiler really sees the preprocessed form, after expansion of #include
directives).
With GCC, you may want to have a single header (including other ones) and pre-compile it.
BTW, splitting a big file into several smaller ones, or merging several small files is not a big deal. So I think it is not very important.
In some cases (embedded C program on a small microcontroller, Arduino like), binary program size is very important, and that could be a reason to have many object files (so many C source files) since you'll only link those that are really needed.
If you are going to place the functions in a library used by possibly many different programs, then placing each function in a separate file has a distinct advantage.
Suppose the library contains 500 functions, and program1 references only 2 of those, while program2 references 150 of them. Then only 2 of the functions will be loaded into the first executable, and only 150 will be loaded into the second one.
If all of the functions were contained in a single file, all 500 functions would be loaded into each of the programs, making them very large and containing code that is never used.