web-dev-qa-db-fra.com

Une fonction très courte peut-elle devenir en ligne même si elle n'était pas explicitement définie en tant que ligne

Je sais par avance que lors de l'écriture d'un programme en C ou C++, même si je déclare une fonction comme "inline", le compilateur est libre de l'ignorer et de décider de ne pas l'étendre à chaque appel.

Le contraire est-il vrai aussi? En d’autres termes, un compilateur peut-il intégrer automatiquement une fonction très courte qui n’était pas définie comme telle si le compilateur pensait que cela entraînerait un gain de performance?

Deux autres sous-questions: ce comportement est-il défini quelque part dans les normes ANSI? C est-il différent de C++ à cet égard, ou se comportent-ils de la même manière?

6
Joe Pineda

inline n'est pas contraignant quant à savoir si une fonction sera ou non insérée par le compilateur. C'était à l'origine ce qu'il était destiné à faire. Mais depuis lors, on s'est rendu compte que le fait de savoir si une fonction vaut la peine d'être en ligne dépend du site d'appels autant que de la fonction elle-même et il est préférable que le compilateur en décide.

De https://en.cppreference.com/w/cpp/language/inline

Étant donné que cette signification du mot clé inline est non contraignante, les compilateurs sont libres d'utiliser la substitution inline pour toute fonction non marquée inline et de générer des appels de fonction à toute fonction marquée inline. Ces choix d'optimisation ne modifient pas les règles relatives aux définitions multiples et aux statistiques partagées répertoriées ci-dessus.

Edit: Puisque vous avez également demandé le C, de https://fr.cppreference.com/w/c/language/inline :

L'intention du spécificateur inline est de servir de conseil au compilateur pour effectuer des optimisations, telles que l'inligne de fonction, qui nécessitent que la définition d'une fonction soit visible sur le site de l'appel. Les compilateurs peuvent (et le font généralement) ignorer la présence ou l'absence du spécificateur inline à des fins d'optimisation.

11
François Andrieux

En ce qui concerne la relation entre C et C++, le spécificateur inline est traité différemment dans chaque langage.

  • En C++: les fonctions inline (et les fonctions analogues à des entités et les variables (depuis C++ 17)) non déclarées auparavant avec une liaison interne auront external linkage et seront visibles à partir d'autres unités de compilation. Etant donné que les fonctions inline résident (généralement) dans des fichiers d’en-tête, cela signifie que la même fonction aura des définitions répétées sur différentes unités de compilation (ceci constituerait une violation de la Une règle de définition mais la inline la rend légale). À la fin du processus de construction (lors de la liaison d'un exécutable ou d'une bibliothèque partagée), les définitions en ligne de la même entité sont fusionnées. De manière informelle, C++ inline signifie: "il peut exister plusieurs définitions identiques de certaines fonctions dans plusieurs fichiers source, mais je veux qu'elles aboutissent à une définition unique".
  • En C: Si extern n'est pas explicitement spécifié, alors une définition de fonction en ligne n'est pas visible depuis d'autres unités de traduction, différentes unités de traduction peuvent avoir des définitions différentes avec le spécificateur inline pour le même nom de fonction. En outre, il peut exister (au plus) une définition pour un nom de fonction qui est à la fois inline et extern et cela qualifie cette fonction comme étant celle visible de l'extérieur (c'est-à-dire est sélectionnée lorsque l'on applique l'adresse de l'opérateur & au nom de la fonction) . La règle de définition unique de C et sa relation avec extern et inline est en quelque sorte différente de C++.

un compilateur peut-il automatiquement intégrer une fonction très courte qui n’était pas définie comme si le compilateur pensait que cela entraînerait un gain de performance?

Limitation:
Lorsque le code utilise un pointeur sur la fonction, celle-ci doit exister non en ligne.

Limitation:
Lorsque la fonction est visible en dehors du fichier .c local (pas static), cela empêche le code en ligne simpliste.

Pas une limitation:
La longueur de la fonction n’est pas une limitation absolue, bien que pratique.

J'ai travaillé avec un processeur intégré qui utilise généralement des fonctions static en ligne. (Le code donné n'utilise pas de pointeur vers eux.)

L'utilité du mot clé inline n'affecte pas la capacité d'un compilateur à une fonction en ligne.

1
chux

En ce qui concerne la norme, le mot clé inline n'a rien à voir avec l'inline.

Les règles (en c ++) sont essentiellement:

  • Une fonction qui est pas déclaré inline ne peut être définie que dans une union de traduction. Il doit encore être analysé dans chaque unité de traduction où il est utilisé.
  • Une fonction déclarée inline doit être définie dans chaque unité de traduction où elle est odr-used (ord-use signifie appeler la fonction ou prendre le pointeur, ...). 

Ainsi, dans un cadre de projet standard, il est presque toujours correct de suivre les deux règles suivantes. Les fonctions définies dans un fichier d’en-tête sont toujours à déclarer inline. Les fonctions définies dans un fichier * .cpp ne sont jamais déclarées inline.

Ceci dit, je pense que le compilateur ne peut pas vraiment tirer de conclusions sur le programmeur qui voulait utiliser ou non le mot clé inline. Le nom du mot clé est un héritage malheureux d’une mauvaise appellation.

0
Handy999