You usually define (not only declare) inlined functions in headers.
And you declare non-inlined functions (e.g. functions whose body is large enough), and define them (i.e. implement them) in one particular compilation unit.
Then the linker resolves the appropriate function names (usually mangled names) at link-time. And you don't want to have multiply defined functions.
Having a function definition provided only by one compilation unit makes the total build time a bit faster.
With link-time optimizations (e.g. the -flto
option to g++
both during compilation and during linking) things become more complicated.
Notice that huge software (some executables are nearly one gigabyte of binary, and simply linking them takes several minutes) bring constraints that a lone programmer don't even imagine. Just try to compile a large free software (Libreoffice, Firefox, Qt5, ...) from its source code to guess the issues.
BTW, you could in principle put all the code of some program in a single source file, but for valid and obvious reasons people don't do that.