In addition to other replies, it must be said that normally linkers work in terms of sections, not functions.
Compilers typically have it configurable whether they put all of your object code into one monolithic section or split it into a number of smaller ones. For example, GCC options to switch on splitting are -ffunction-sections
(for code) and -fdata-sections
(for data); MSVC option is /Gy
(for both). -fnofunction-sections
, -fnodata-sections
, /Gy-
respectively to put all code or data into one section.
You might 'play' with compiling your modules in both modes and then dumping them (objdump
for GCC, dumpbin
for MSVC) to see the generated object file structure.
Once a section is formed by the compiler, for the linker it is a unit. Sections define symbols and refer to symbols defined in other sections. The linker will build dependency graph between the sections (starting at a number of roots) and then either disband or keep each of them entirely. So, if you have a used and an unused function in a section, the unused function will be kept.
There are both benefits and drawbacks in either mode. Turning splitting on means smaller executable files, but larger object files and longer linking times.
It has to also be noted that in C++, unlike C, there are certain situations where the One Definition Rule is relaxed, and multiple definitions of a function or data object are allowed (for example, in case of inline functions). The rules are formulated in such way that the linker is allowed to pick any definition.
From the point of view of sections, putting inline functions together with non-inline ones would mean that in a typical use scenario the linker would typically be forced to keep virtually every definition of every inline function; that would mean excessive code bloat. Therefore, such functions and data are normally put into their own sections regardless of compiler command line options.
UPDATE: As @janm correctly reminded in his comment, the linker must also be instructed to get rid of unreferenced sections by specifying --gc-sections
(GNU) or /opt:ref
(MS).