web-dev-qa-db-fra.com

Les fonctions inutilisées sont-elles optimisées?

Une question assez simple ... De nos jours, les compilateurs ont tendance à faire beaucoup d'optimisations. Suppriment-ils également les fonctions inutilisées de la sortie finale?

49
Paul Manta

Cela dépend du compilateur. Visual C++ 9 peut le faire - les fonctions inutilisées static sont supprimées à la phase de compilation (il y a même un avertissement C4505 pour cela), les fonctions inutilisées avec liaison externe peuvent être supprimées à la phase de liaison - en fonction des paramètres de l'éditeur de liens .

26
sharptooth

MSVC (le compilateur/éditeur de liens Visual Studio) peut le faire si vous compilez avec /Gy et liez avec /OPT:REF .

GCC/binutils peut le faire si vous compilez avec -ffunction-sections -fdata-sections et liez avec --gc-sections .

Je ne connais pas les autres compilateurs.

21
rubenvb

En règle générale, la réponse est:

Oui: pour les fonctions static inutilisées.

Non: pour les fonctions inutilisées disponibles à l'échelle mondiale.

Le compilateur ne sait pas si une autre unité de compilation y fait référence. De plus, la plupart des types de module objet ne permettent pas de supprimer des fonctions après la compilation et ne fournissent pas non plus à l'éditeur de liens un moyen de savoir s'il existe des références internes. (L'éditeur de liens peut dire s'il y en a externes .) Certains éditeurs de liens peuvent le faire mais beaucoup de choses fonctionnent contre cela.

Bien sûr, une fonction dans son propre module ne sera chargée inutilement par aucun éditeur de liens, sauf si elle fait partie d'une bibliothèque partagée. (Parce qu'il pourrait être référencé à l'avenir lors de l'exécution, évidemment.)

16
DigitalRoss

De nombreux compilateurs le font, mais cela dépend de l'implémentation particulière. Les versions de débogage incluent souvent toutes les fonctions, pour leur permettre d'être invoquées ou examinées à partir du débogueur. De nombreux compilateurs de systèmes embarqués, pour des raisons que je ne comprends pas totalement (*), incluront toutes les fonctions dans un fichier objet s'ils en contiennent, mais omettront entièrement tous les fichiers objet qui ne sont pas utilisés du tout.

Notez que dans les langages qui prennent en charge la réflexion (par exemple Java, C #, vb.net, etc.), il est possible, compte tenu du nom d'une fonction, de créer une référence à celle-ci lors de l'exécution même si aucune référence n'existe dans le code. Par exemple, une routine peut accepter une chaîne de la console, la munir d'une certaine manière et générer un appel à une fonction de ce nom. Il n'y aurait aucun moyen pour un compilateur ou un éditeur de liens de savoir quels noms pourraient être ainsi générés, et donc aucun moyen de savoir quelles fonctions peuvent être omises en toute sécurité du code. Cependant, aucune difficulté de ce type n'existe en C ou C++, car il n'existe aucun moyen défini pour que le code crée une référence à une fonction, une variable ou une constante sans qu'une référence explicite existe dans le code. Certaines implémentations peuvent arranger les choses pour que les constantes ou variables déclarées consécutivement soient stockées consécutivement, et on pourrait donc créer une référence à une déclarée plus tard en ajoutant un décalage à une déclarée plus tôt, mais le comportement de ces astuces est explicitement non garanti par les normes C ou C++.

(*) Je comprends que cela facilite la compilation et la liaison, mais les ordinateurs d'aujourd'hui ne devraient avoir aucun problème à exécuter des algorithmes de compilation et de liaison plus sophistiqués que ce qui aurait été pratique au cours des dernières décennies. Si rien d'autre, une méthode de pré-compilation/pré-liaison/compilation/lien en deux passes pourrait sur la phase de pré-compilation/liaison produire une liste des choses qui sont utilisées, puis sur la "vraie" phase de compilation/liaison omettre ceux qui ne le sont pas.

5
supercat

Avec gcc, si vous activez les optimisations, il peut supprimer les fonctions inutilisées et le code mort.

Plus d'informations sur les optimisations gcc peuvent être trouvées ici

5
rsachetto

La plupart du temps, oui. Son souvent appelé décapage de l'éditeur de liens.

3
Goz

En ce qui concerne MS, c'est l'éditeur de liens qui s'occupe de cela pendant la phase de liaison et le compilateur peut vous avertir des fonctions statiques inutilisées (portée du fichier). Si vous voulez que l'éditeur de liens supprime les fonctions inutilisées, vous utilisez l'option / OPT: REF :

2
ralphtheninja

Sous MSVC et avec des fonctions globales ou variables, vous pouvez utiliser __ declspec (selectany) .

Il supprimera la fonction ou la variable si elle n'a pas été référencée dans le code si l'option de l'éditeur de liens/OPT: REF (Optimisations) est sélectionnée.

1
handcoded