En plus des autres réponses, il faut dire que normalement les linkers travaillent en termes de sections et non de fonctions.
Les compilateurs ont généralement la possibilité de configurer s'ils mettent tout votre code objet dans une section monolithique ou s'ils le divisent en plusieurs sections plus petites. Par exemple, les options de GCC pour activer le fractionnement sont les suivantes -ffunction-sections
(pour le code) et -fdata-sections
(pour les données) ; l'option MSVC est /Gy
(pour les deux). -fnofunction-sections
, -fnodata-sections
, /Gy-
respectivement pour mettre tout le code ou les données dans une seule section.
Vous pouvez "jouer" avec la compilation de vos modules dans les deux modes et ensuite les vider ( objdump
pour GCC, dumpbin
pour MSVC) pour voir la structure du fichier objet généré.
Une fois qu'une section est formée par le compilateur, pour l'éditeur de liens, elle constitue une unité. Les sections définissent des symboles et font référence à des symboles définis dans d'autres sections. L'éditeur de liens construira un graphe de dépendance entre les sections (en commençant par un certain nombre de racines), puis il dissoudra ou conservera chacune d'entre elles entièrement. Ainsi, si vous avez une fonction utilisée et une fonction non utilisée dans une section, la fonction non utilisée sera conservée.
Les deux modes présentent des avantages et des inconvénients. Activer le fractionnement signifie des fichiers exécutables plus petits, mais des fichiers objets plus gros et des temps de liaison plus longs.
Il faut également noter qu'en C++, contrairement au C, il existe certaines situations où la règle de la définition unique est relâchée et où plusieurs définitions d'une fonction ou d'un objet de données sont autorisées (par exemple, dans le cas des fonctions en ligne). Les règles sont formulées de telle manière que l'éditeur de liens est autorisé à choisir n'importe quelle définition.
Du point de vue des sections, mettre les fonctions inline avec les fonctions non-inline signifierait que dans un scénario d'utilisation typique, l'éditeur de liens serait forcé de garder virtuellement chaque définition de chaque fonction inline ; cela signifierait un gonflement excessif du code. Par conséquent, ces fonctions et données sont normalement placées dans leurs propres sections, indépendamment des options de la ligne de commande du compilateur.
UPDATE : Comme @janm l'a correctement rappelé dans son commentaire, il faut également demander au linker de se débarrasser des sections non référencées en spécifiant --gc-sections
(GNU) ou /opt:ref
(MS).