L’arrivée de C++17 – les variables inline

Salut à tous ! L’article d’aujourd’hui porte sur une fonctionnalité de C++17les variables inline.

La P0386 a étendu l’utilisation du mot-clef inline aux variables membres statiques et aux variables globales. Comme pour les fonctions, une variable  inline peut donc être définie dans des unités de traduction différentes. En effet, il s’agit du but premier du mot-clef inline pour les fonctions, l’indice d’optimisation sur l’inlining pour le compilateur n’est qu’un bonus (et le compilateur n’a aucune obligation). Dans ce cas, l’éditeur de liens choisira à son gré l’une des définitions (si les définitions sont différentes, il s’agit d’un undefined behavior).

Avant tout cela, la définition de variables statiques nécessitait de séparer la déclaration de la définition, de manière à respecter l’ODR :

Bien entendu, il existait déjà des solutions partielles. On peut par exemple utiliser une fonction  inline qui retourne le paramètre :

Dans ce cas, en plus d’être plus verbeux à l’utilisation en raison de la syntaxe avec l’appel de fonction, le comportement est légèrement différent puisque s_ ne sera construite qu’à l’appel de la fonction (ce qui pour des types plus complexes peut être un problème).

L’arrivée de constexpr a permis de simplifier la chose :

Bien pratique n’est-ce pas ? Le souci étant que tout ne se plie pas aux règles de constexpr et ce n’est donc pas utilisable dans le cas général. De plus, si i est odr-used, il est tout de même nécessaire de définir i en dehors de la classe :

C’est pourquoi C++17 propose les variables  inline, qui peuvent donc être définies de multiples fois :

Dans le cas d’une variable globale à la portée d’un namespace par exemple, on a ici la garantie que l’adresse de la variable (ou de la constante) sera la même dans toutes les unités de traduction. Sémantiquement, cela revient à une variable extern dont la définition n’a pas être placée dans une seule unité de traduction puisque les variables globales inline ont un external linkage.

A l’inverse des fonctions, une variable membre définie dans la définition d’une classe n’est pas automatiquement  inline, mais doit être explicitement déclarée comme tel. Cette décision a certainement vocation à ne pas interférer avec le code existant.

Les variables membres statiques constexpr sont implicitement  inline. Il est toujours possible de faire une définition en dehors de la classe mais cela est d’ores et déjà déprécié et sera potentiellement retiré du standard par la suite.

Merci à tous de m’avoir lu, et je vous dis à bientôt !

Références et ressources

%d bloggers like this: