Un compilateur / lieur C ++ est-il autorisé à supprimer les méthodes inutilisées?

Un compilateur ou un éditeur de liens C ++ (conforme à toute norme C ++) est-il autorisé à supprimer une méthode non utilisée? Les compilateurs semblent être autorisés à supprimer les fonctions statiques non utilisées, les lieurs sont autorisés à supprimer les fonctions inutilisées. Mais je n’ai trouvé aucune information à quoi cela ressemble pour les méthodes de classes. Lorsque la méthode est virtuelle, cela devient vraiment intéressant.

La norme C ++ fonctionne à un niveau plus abstrait. Il n’est pas nécessaire qu’une implémentation C ++ soit réellement composée d’outils individuels, tels qu’un compilateur et un éditeur de liens.

Incidemment, je viens de parcourir le brouillon PDF sur ma machine et il n’ya qu’une seule occurrence du mot “éditeur de liens” dans l’ensemble du document de 1368 pages, et même celui-ci ne figure que dans une note de bas de page sur les jeux de caractères.

La norme parle en fait de la règle dite “as-if” .

Citant le § 1.9:

(…) des implémentations conformes sont requirejses pour émuler (uniquement) le comportement observable de la machine abstraite, comme expliqué ci-dessous.

Dans une note de bas de page pour cette phrase, il est également indiqué:

Cette disposition est parfois appelée règle “as-if”, car une implémentation est libre de ne pas respecter une exigence de la présente Norme internationale à condition que le résultat soit comme si l’exigence avait été respectée , dans la mesure où le comportement observable l’avait déterminé. du programme.

Si une fonction n’est utilisée d’aucune manière dans votre programme, elle ne peut avoir aucun impact sur le comportement observable. La seule règle “as-if” donne ainsi au compilateur ou à l’éditeur de liens la liberté de le supprimer du résultat exécutable.

Oui.

Si la méthode n’est pas utilisée, il n’y a aucun moyen de savoir si elle a été supprimée – un éditeur de liens peut le faire. Notez que prendre l’adresse d’une méthode peut bien compter comme “utilisant” la méthode – et pas seulement l’appeler réellement.

Les lieurs sont susceptibles de supprimer des fonctions membres non virtuelles (c’est simple et cela économise de l’espace).

Ils pourraient supprimer les fonctions virtuelles inutilisées, mais le compilateur devrait append de nombreuses informations sur les fonctions virtuelles qu’il appelait afin que l’éditeur de liens puisse supprimer les fonctions inutilisées (et éventuellement compacter la vtable). En pratique, je ne pense pas que les linkers agissent de la sorte car le gain est probablement faible et les efforts de développement requirejs plutôt importants.

Comme la norme C ++ ne dit rien à ce sujet, il est probablement plus exact de dire que cela n’empêche pas la suppression des fonctions membres inutilisées, que de dire que cela permet leur suppression. Mais il est également valable de dire que cela n’exige pas leur retrait. Cela est d’ailleurs vrai pour toutes les fonctions.

Si des programmes de la chaîne de construction (compilateur, éditeur de liens, etc.) peuvent détecter qu’aucun symbole (par exemple, une fonction membre statique ou non statique) n’est utilisée, ils peuvent les supprimer en toute sécurité.

Le problème pratique le plus difficile est probablement de détecter qu’une fonction membre non statique n’est pas appelée. Encore plus, s’il est virtuel, puisque le type statique d’un object est ce qui détermine le remplacement d’une fonction virtuelle appelée. La détection de tels cas n’est pas en principe impossible, mais elle nécessiterait une parsing approfondie.

En fin de compte, la qualité de la mise en œuvre de la chaîne de construction dépendra de la qualité, car la norme ne requirejs rien de particulier. Cela revient à savoir si le fournisseur choisit de mettre en œuvre de telles optimisations. Et comme il ne s’agit pas d’un comportement recherché par de nombreux développeurs (les personnes les plus susceptibles de le rechercher auront un fétichisme d’optimisation prématuré), peu le voudraient.

Les méthodes de classe sont en ligne lorsqu’elles sont définies dans la définition de classe. Lorsqu’elles sont implémentées séparément, ce sont des fonctions simples avec un premier paramètre masqué, qui devient le pointeur sur l’instance qui appelle cette fonction en tant que membre de sa classe. Il n’y a pas de problème à supprimer une méthode de classe non utilisée.

Les compilateurs pourraient vérifier la façon dont la vtable d’instances est utilisée pour détecter les membres virtuels inutilisés, mais cela demande beaucoup de suivi pour de petits avantages. Il y a quelques années, GCC ne l’a pas fait.

Le mot clé volatile ou exportation enregistre les variables et fonctions / méthodes de classe en supprimant les optimisations.