Gabriel Dos Reis propose une alternative simple à l’utilisation du préprocesseur C,
pour accéder à l'API d'une bibliothèque lors du CppCon 2015
La plupart des logiciels est construit en utilisant un certain nombre de bibliothèques logicielles, soient des bibliothèques fournies par la plate-forme utilisée ou des bibliothèques internes intégrés au logiciel lui-même ou encore de bibliothèques tierces. Pour utiliser une bibliothèque, le développeur a besoin d’accéder à son API et à son implémentation. Dans la famille des langages C, l'interface d’une bibliothèque est accessible en incluant les fichiers d'en-tête appropriés comme suit : #include <ma_librairie.h>. Les modules fournissent une alternative plus simple pour utiliser les bibliothèques logicielles qui permet une meilleure gestion de la compilation et élimine bon nombre des problèmes inhérents à l'utilisation du préprocesseur C pour accéder à l'API d'une bibliothèque.
Pourquoi utiliser les modules ?
La réponse se trouve à plusieurs niveaux. Tout d’abord, il faut noter que le mécanisme utilisant #include est une très mauvaise façon de faire et ceci pour plusieurs raisons. La première est le fait qu’à chaque inclusion d’entête, le compilateur doit prétraiter cet entête et analyser son texte ainsi que chaque entête inclus dans ce dernier. Ce processus doit être répété partout où la même inclusion a été effectuée, ce qui implique une quantité de travail énorme et redondant. Une autre raison est liée au fait que les directives du type #include soient fragiles parce qu’elles sont traitées comme des inclusions textuelles par le préprocesseur et sont donc soumises aux directives de macro actives au moment de l’inclusion. Si une directive de macro entre en collision avec un nom de bibliothèque, cela peut provoquer des erreurs de compilation ou tout simplement casser l’API de la bibliothèque. Les programmeurs ont également adopté un certain nombre de conventions pour contourner les limites du préprocesseur C. Pour éviter les collisions par exemple, certains développeurs de librairies et de framework vont utiliser des noms d’entêtes précédés de (_) alors que ces derniers ne devraient pas être des macros.
Avantages des modules
Les modules permettent d'améliorer l'accès aux API des bibliothèques logicielles en remplaçant le modèle d'inclusion textuelle du préprocesseur avec un modèle sémantique, plus efficace et plus robuste. Du point de vue du développeur, le code ne change que légèrement, parce que c'est un import qui est utilisé à la place d'une directive #include du préprocesseur: import std.io. Cependant, l’importation de module est se comporte tout à fait différemment de la directive #include correspondante. Lorsque le compilateur voit une importation de module, il charge une représentation binaire du module et rend son API directement disponible pour l'application. Les directives du préprocesseur qui précèdent la déclaration d'importation n’ont aucune incidence sur l'API fournie, parce que le module lui-même a été compilé comme un module autonome. En outre, tous les flags de liaison nécessaires pour utiliser le module sont automatiquement fournis lors de l’importation du module. Ce modèle d'importation sémantique résout un grand nombre des problèmes du modèle d’inclusion du préprocesseur. Le temps de compilation est nettement optimisé car le module est compilé une seule fois et son importation est une opération à temps constant. L’API de chaque module est analysé une seule fois ce qui réduit le temps de compilation de NxM à N+M avec M, le nombre d’unités du programme et N le nombre d’entêtes inclus.Chaque module est analysé comme une entité autonome, avec donc un environnement préprocesseur cohérent. Le développeur n’a donc plus besoin d’utiliser des astuces ou conventions comme faire précéder ses noms d’en-têtes par (_). En outre quand un import est rencontré, les directives du préprocesseur sont ignorées. Une bibliothèque logicielle ne peut donc pas affecter la façon dont une autre est compilée, éliminant les dépendances quant à l’ordre d’importation des en-têtes.
Limites des modules
Les modules ne résolvent cependant pas tous les problèmes liés au modèle du préprocesseur. Il n’est pas possible d’éliminer complètement les en-têtes car il ne serait pas réaliste de vouloir faire faire des changements radicaux quant à la façon qu’ont les applications ou bibliothèques logicielles existantes d’utiliser des inclusions et les modules ont besoin d’interagir avec des bibliothèques existantes. Les modules ne prennent pas encore en compte la notion de versioning. Les développeurs devront donc faire avec les mécanismes de gestion de version existants. Contrairement à certains langages, les modules en C++ n’incluent aucune notion d’espaces de noms si bien qu’une structure déclarée dans un module sera toujours en conflit avec une autre structure du même nom déclarée dans un module différent.
Source : YouTube
Et vous ?
Que pensez vous de cette alternative à l'utilisation du préprocesseur C ?
Voir aussi
le forum Langage C++
la rubrique C++ (Cours, Tutoriels, FAQ, etc.)
Partager