Partager via


inline, __inline, __forceinline

Les spécificateurs inline and __inline ordonnent au compilateur d'insérer une copie du corps de la fonction à chaque endroit où la fonction est appelée.

inline function_declarator;   
__inline function_declarator;   // Microsoft Specific
__forceinline function_declarator;   // Microsoft Specific

Notes

L'insertion (appelée expansion incluse ou inclusion) se produit uniquement si l'analyse des coût/avantage du compilateur montre qu'elle est rentable. L'expansion incluse allège la surcharge d'appel de fonction au coût potentiel d'une plus grande taille de code.

Le mot clé __forceinline substitue l'analyse coût-avantage et repose à la place sur un jugement du programmeur. Soyez prudent lorsque vous utilisez __forceinline. L'utilisation aveugle de __forceinline peut entraîner un plus grand code avec seulement des gains de performance marginaux, ou même, dans certains cas, des pertes de performance (causées par exemple par une pagination accrue d'un fichier exécutable plus grand).

L'utilisation de fonctions incluse peut rendre votre programme plus rapide car elles éliminent la surcharge associée à des appels de fonction. Les fonctions qui sont développées en inclusion sont soumises à des optimisations de code non disponibles pour les fonctions normales.

Le compilateur traite les options d'expansion inline et les mots clés en tant que suggestions. Rien ne garantit que les fonctions seront incluses. Vous ne pouvez pas forcer le compilateur à inclure une fonction particulière, même avec le mot clé __forceinline. Lors de la compilation avec /clr, le compilateur n'appliquera pas la fonctionnalité inclusion à une fonction s'il existe des attributs de sécurité appliqués à la fonction.

Le mot clé inline est disponible uniquement en C++. Les mots clés __inline et __forceinline sont disponibles à la fois dans C et dans C++. Pour assurer la compatibilité avec les versions antérieures, _inline est un synonyme de __inline.

Le mot clé inline indique au compilateur que l'expansion inclusion est préférée. Toutefois, le compilateur peut créer une instance séparée de la fonction (instancié) et créer des standards appelant des liens au lieu d'insérer le code inclus. Les deux cas où cela peut se produire sont :

  • Fonctions récursives.

  • Fonctions qui sont référencés par l'intermédiaire d'un pointeur ailleurs dans l'unité de traduction.

Ces raisons peuvent interférer avec l'inclusion, comme le peuvent d'autres, à la discrétion du compilateur ; vous ne devez pas dépendre du spécificateur inline pour imposer à une fonction d'être incluse.

Comme avec les fonctions normales, il n'existe aucun ordre d'évaluation défini des arguments à une fonction incluse. En pratique, il peut être différent de l'ordre dans lequel les arguments sont évalués lorsqu'ils sont passés à l'aide d'une fonction normale appelée protocole.

L'option d'optimisation du compilateur /Ob aide à déterminer si les expansions des fonctions incluses se produisent réellement.

/LTCG effectue l'inclusion entre modules qu'elle ait été demandée ou non dans le code source.

Exemple 1

// inline_keyword1.cpp
// compile with: /c
inline int max( int a , int b ) {
   if( a > b ) 
      return a;
   return b;
}

Les fonctions membres d'une classe peuvent être déclarées incluse en utilisant le mot clé inline ou en plaçant la définition de la fonction dans la définition de la classe.

Exemple 2

// inline_keyword2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;

class MyClass {
public:
   void print() { cout << i << ' '; }   // Implicitly inline
private:
   int i;
};

Spécifique à Microsoft

Le mot clé __inline est équivalent à inline.

Même avec __forceinline, le compilateur ne peut pas inclure le code dans toutes les circonstances. Le compilateur ne peut pas inclure une fonction si :

  • La fonction ou son appelant est compilée avec /Ob0 (option par défaut pour les versions Debug).

  • La fonction et l'appelant utilisent différents types de gestion des exceptions (gestion des exceptions C++ dans un, gestion structurée des exceptions dans l'autre).

  • La fonctions a une liste d'arguments variable.

  • La fonction utilise l'assembly incluse, sauf si elle est compilée avec /Og, /Ox, /O1, ou /O2.

  • La fonction est récursive et non accompagnée par #pragma inline_recursion(on). Avec le pragma, les fonctions récursives sont incluse dans une profondeur par défaut de 16 appels. Pour réduire la profondeur d'inclusion, utilisez le pragma inline_depth.

  • La fonction est virtuelle et est appelée virtuellement. Les appels directs aux fonctions virtuelles peuvent être inclus.

  • Le programme prend l'adresse de la fonction et l'appel est effectué via le pointeur vers la fonction. Les appels directs aux fonctions ayant eu leur adresse prise peuvent être inclus.

  • La fonction est également marquée avec le modificateur naked __declspec.

Si le compilateur ne peut pas inclure une fonction déclarée avec __forceinline, il génère un avertissement de niveau 1.

Les fonctions récursives peuvent être incluses substituées à une profondeur spécifiée par le pragma inline_depth, jusqu'au maximum de 16 appels. Après cette profondeur, les appels de fonction récursive sont traités comme des appels à une instance de la fonction. La profondeur à laquelle les fonctions récursives sont examinées par l'heuristique incluse ne peut pas dépasser 16. Le pragma d'inline_recursion contrôle l'expansion incluse d'une fonction actuellement sous expansion. Consultez l'option du compilateur de Activer/Désactiver de fonction inline (/Ob) pour des informations connexes.

END Spécifique à Microsoft

+Pour plus d'informations sur l'utilisation de inline specifier, consultez:

Voir aussi

Référence

Mots clés C++

noinline

auto_inline