inline
specifier
Le spécificateur inline , lorsqu'il est utilisé dans la decl-specifier-seq d'une fonction, déclare la fonction comme étant une fonction inline .
Une fonction définie entièrement à l'intérieur d'une définition de classe/struct/union , qu'il s'agisse d'une fonction membre ou d'une fonction friend non-membre, est implicitement une fonction inline sauf si elle est attachée à un module nommé (depuis C++20) .
|
Une fonction déclarée constexpr ou consteval (depuis C++20) lors de sa première déclaration est implicitement une fonction inline. Une fonction supprimée est implicitement une fonction inline : sa définition (supprimée) peut apparaître dans plusieurs unités de traduction. |
(depuis C++11) |
|
Le spécificateur inline , lorsqu'il est utilisé dans une séquence de spécificateurs de déclaration d'une variable avec durée de stockage statique (membre de classe statique ou variable de portée de namespace), déclare la variable comme étant une variable inline . Un membre de données statique déclaré constexpr lors de sa première déclaration est implicitement une variable inline. |
(depuis C++17) |
Table des matières |
Explication
Une fonction inline ou variable inline (depuis C++17) possède les propriétés suivantes :
- La définition d'une fonction inline ou variable (since C++17) doit être accessible dans l'unité de traduction où elle est utilisée (pas nécessairement avant le point d'accès).
- Une fonction inline ou variable (since C++17) avec liaison externe (par exemple non déclarée static ) possède les propriétés supplémentaires suivantes :
-
- Il peut y avoir plus d'une définition d'une fonction inline ou variable (depuis C++17) dans le programme tant que chaque définition apparaît dans une unité de traduction différente et (pour les fonctions inline non statiques et variables (depuis C++17) ) toutes les définitions sont identiques. Par exemple, une fonction inline ou une variable inline (depuis C++17) peut être définie dans un fichier d'en-tête inclus dans plusieurs fichiers source.
- Elle doit être déclarée inline dans chaque unité de traduction.
- Elle a la même adresse dans chaque unité de traduction.
Dans une fonction en ligne,
- Les objets statiques locaux à la fonction dans toutes les définitions de fonctions sont partagés entre toutes les unités de traduction (ils font tous référence au même objet défini dans une unité de traduction).
- Les types définis dans toutes les définitions de fonctions sont également les mêmes dans toutes les unités de traduction.
|
Les variables const inline au niveau de la portée du namespace ont une liaison externe par défaut (contrairement aux variables const non-inline non-volatile). |
(depuis C++17) |
L'intention initiale du mot-clé inline était de servir d'indicateur à l'optimiseur que la substitution en ligne d'une fonction est préférable à un appel de fonction, c'est-à-dire qu'au lieu d'exécuter l'instruction CPU d'appel de fonction pour transférer le contrôle au corps de la fonction, une copie du corps de la fonction est exécutée sans générer l'appel. Cela évite la surcharge créée par l'appel de fonction (transmission des arguments et récupération du résultat) mais peut entraîner un exécutable plus volumineux car le code de la fonction doit être répété plusieurs fois.
Puisque la substitution en ligne n'est pas observable dans la sémantique standard, les compilateurs sont libres d'utiliser la substitution en ligne pour toute fonction non marquée inline , et sont libres de générer des appels de fonction pour toute fonction marquée inline . Ces choix d'optimisation ne modifient pas les règles concernant les définitions multiples et les statiques partagés mentionnées ci-dessus.
|
Étant donné que la signification du mot-clé inline pour les fonctions est passée de "l'inlining est préféré" à "les définitions multiples sont autorisées" depuis C++98, cette signification a été étendue aux variables. |
(depuis C++17) |
Notes
Si une fonction en ligne ou variable (depuis C++17) avec liaison externe est définie différemment dans différentes unités de traduction, le programme est mal formé, aucun diagnostic requis.
Le spécificateur inline ne peut pas être utilisé avec une déclaration de fonction ou de variable (depuis C++17) au niveau bloc (à l'intérieur d'une autre fonction).
Le spécificateur inline ne peut pas redéclarer une fonction ou une variable (depuis C++17) qui a déjà été définie dans l'unité de traduction comme non-inline.
Les fonctions membres générées implicitement et toute fonction membre déclarée comme par défaut lors de sa première déclaration sont inline comme toute autre fonction définie à l'intérieur d'une définition de classe.
Si une fonction en ligne est déclarée dans différentes unités de traduction, les ensembles accumulés des arguments par défaut doivent être identiques à la fin de chaque unité de traduction.
En C, les fonctions inline ne doivent pas nécessairement être déclarées inline dans chaque unité de traduction (au plus une peut être non- inline ou extern inline ), les définitions de fonctions ne doivent pas nécessairement être identiques (mais le comportement du programme n'est pas spécifié s'il dépend de celle qui est appelée), et les statiques locales à la fonction sont distinctes entre les différentes définitions de la même fonction.
|
Voir les membres de données statiques pour les règles supplémentaires concernant les membres statiques inline. Les variables inline éliminent le principal obstacle à l'empaquetage du code C++ sous forme de bibliothèques header-only. |
(depuis C++17) |
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_inline_variables
|
201606L
|
(C++17) | Variables inline |
Mots-clés
Exemple
En-tête "example.h" :
#ifndef EXAMPLE_H #define EXAMPLE_H #include <atomic> // une fonction incluse dans plusieurs fichiers source doit être inline inline int sum(int a, int b) { return a + b; } // une variable avec liaison externe incluse dans plusieurs fichiers source doit être inline inline std::atomic<int> counter(0); #endif
Fichier source #1 :
#include "example.h" int a() { ++counter; return sum(1, 2); }
` et contient des termes spécifiques au C++ qui doivent être préservés selon les instructions. Seul le texte en dehors de ces balises aurait été traduit, mais dans cet exemple, il n'y a pas de texte à traduire en dehors du code.
Fichier source #2 :
#include "example.h" int b() { ++counter; return sum(3, 4); }
` et contient des termes spécifiques au C++. Aucune traduction n'a été effectuée sur le contenu du code, conformément aux instructions.
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| CWG 281 | C++98 |
une déclaration de fonction amie pouvait utiliser le spécificateur inline
même si la fonction amie n'est pas une fonction inline |
interdire de telles utilisations |
| CWG 317 | C++98 |
une fonction pouvait être déclarée inline même si elle a une définition
non-inline dans la même unité de traduction avant la déclaration |
le programme est mal-
formé dans ce cas |
| CWG 765 | C++98 |
un type défini dans une fonction inline pourrait
être différent dans différentes unités de traduction |
ces types sont les mêmes
dans toutes les unités de traduction |
| CWG 1823 | C++98 |
les littéraux de chaîne dans toutes les définitions d'une fonction
inline étaient partagés entre toutes les unités de traduction |
l'exigence est supprimée pour des raisons de
cohérence et d'implémentations |
| CWG 2531 | C++17 |
un membre de données static pouvait être implicitement inline même si
il n'était pas déclaré constexpr lors de sa première déclaration |
il n'est pas implicitement
inline dans ce cas |
Voir aussi
|
Documentation C
pour
inline
|