Modules C ++ – pourquoi ont-ils été supprimés de C ++ 0x? Seront-ils de retour plus tard?

Je viens de découvrir cet ancien brouillon C ++ 0x sur les modules en C ++ 0x.

L’idée était de sortir du système actuel .h / .cpp en écrivant uniquement des fichiers .cpp qui généreraient ensuite des fichiers de module lors de la compilation, qui seraient ensuite utilisés par les autres fichiers .cpp.

Cela ressemble à une fonctionnalité vraiment géniale.

Mais ma question est la suivante: pourquoi ont-ils supprimé C ++ 0x? Était-ce à cause de trop de difficultés techniques? Manque de temps? Et pensez-vous qu’ils envisageront d’y travailler pour une version ultérieure de C ++?

De l’ état de C ++ Evolution (Post San Francisco 2008) , la proposition Modules a été classée dans la catégorie “Intitulé pour un TR distinct”:

Ces sujets sont jugés trop importants pour attendre une autre norme après C ++ 0x avant d’être publiés, mais trop expérimentaux pour être finalisés à temps pour la prochaine norme. Par conséquent, ces fonctionnalités seront fournies par un rapport technique dès que possible.

La proposition de modules n’était tout simplement pas prête et l’attendre aurait retardé la finalisation de la norme C ++ 0x. Il n’a pas été vraiment supprimé, il n’a jamais été incorporé dans le document de travail.

Brouillon des modules C ++ (spécification technique après C ++ 17)

Un brouillon et plusieurs mises à jour de la spécification du module C / C ++ ont été publiés par WG21 sur open-std.org. Je ne lierai que les derniers documents ici:

  • Version de travail, extensions C ++ pour les modules N4610 (octobre 2016).
  • Quasortingème révision publiée sous le numéro P0142R0 (mars 2016).
  • Libellé des modules publié sous le numéro P0143R2 (mars 2016).
  • L’équipe Clang a publié une deuxième révision de leurs modifications: P0273R1 (octobre 2016).

Les articles de blog suivants contiennent un résumé des réunions de normalisation et en particulier un résumé de l’état actuel du projet de modules:

  • Rapport de voyage: Réunion sur les normes C ++ à Lenexa (mai 2015).
  • Rapport de voyage: Réunion sur les normes C ++ à Kona (octobre 2015).
  • Rapport de voyage: Réunion sur les normes C ++ à Jacksonville (février 2016).
  • Rapport de voyage: Réunion sur les normes C ++ à Oulu (juin 2016).
  • Rapport de voyage: Réunion sur les normes C ++ à Issaquah (novembre 2016).

Mise à jour: Comme expliqué dans le rapport de voyage Kona auquel j’ai fait référence ci-dessus, il y a actuellement deux propositions concurrentes, l’une de Microsoft et l’autre de Clang. La solution proposée par Microsoft n’autorise pas l’exportation de macros, tandis que la solution de l’équipe Clang prend en charge l’exportation de macros. Jusqu’à présent, seul Microsoft a officiellement soumis un brouillon pour une spécification de module.

Spécification du module proposée par Microsoft

Voici un rapide aperçu des concepts les plus importants contenus dans cette proposition. En tant que projet, cela pourrait encore changer. Les nouveaux modules standard seront notamment les suivants:

Un mot-clé de module pour déclarer un module, plusieurs fichiers peuvent le déclarer pour construire un module (mais pour chaque module, une seule unité de compilation peut contenir une section export {} ):

 module M; 

Un mot-clé d’importation pour importer des modules, au lieu d’ import , pourrait également être utilisé à l’ using module , de sorte qu’un nouveau mot-clé d’importation pourrait être évité.

 import std.io; import module.submodule; 

Une syntaxe d’ export , qui définit les déclarations publiques faisant partie de ce module, les déclarations non-interface qui ne doivent pas être exscopes dans le cadre du module seront définies en dehors du bloc d’exportation. Les déclarations peuvent être tout type de déclaration en C / C ++, c’est-à-dire non seulement des fonctions mais aussi des variables, des structures, des modèles, des espaces de noms et des classes:

 export { int f(int); double g(double, int); int foo; namespace Calc { int add(int a, int b); } } void not_exported_function(char* foo); 

Un changement important des modules sera que les macros et les définitions de préprocesseur seront locales aux modules et ne seront pas exscopes. Ainsi, les macros n’ont aucun impact sur les modules importés:

 #define FILE "my/file" import std.io; //will not be impacted by the above definition 

Il est important de noter que le préprocesseur et les modules actuels peuvent coexister et que les en-têtes peuvent toujours être utilisés pour inclure des macros.

Pour plus d’informations, je suggère de lire le projet.

Modules Clang

Clang a travaillé sur une implémentation de modules qui peut être trouvée sur la page des modules de clang . Cependant, clang n’implémente pas actuellement de syntaxe concrète pour les modules, c’est-à-dire qu’aucune des syntaxes mentionnées ci-dessus n’a été implémentée par Clang. Pour expliquer cela, la page contient la déclaration suivante:

À l’heure actuelle, il n’y a pas de syntaxe C ou C ++ pour les déclarations d’importation. Clang suivra la proposition de modules au sein du comité C ++. Voir la section Comprend les importations pour voir comment les modules sont importés aujourd’hui.

La partie principale actuellement implémentée par Clang est le “Module Map Language” qui permet d’écrire des cartes de module pour du code existant qui utilise encore des fichiers d’en-tête.

Exportations de macros à partir de modules

Comme mentionné ci-dessus, il est encore difficile de savoir si les exportations de macros feront partie des modules TS définitifs. Dans P0273R1, la syntaxe suivante a été proposée pour l’exportation de macros:

 #export define MAX(A,B) ((A) > (B)) ? (A) : (B); 

Clang est le premier compilateur à commencer à travailler sur des modules avant même que la standardisation ne soit terminée. Il n’y a pas encore beaucoup de documentation, mais un exemple de code peut être trouvé ici:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/

Quelques commentaires de Douglas Gregor (le développeur qui les implémente):
http://clang-developers.42468.n3.nabble.com/C-modules-td3619936.html

En théorie, vous pouvez définir un ensemble de macros d’aide telles que begin_module, end_module, import_module pour vous protéger de toute modification probable de la syntaxe à venir.

EDIT 1:
Douglas Gregor a publié une présentation sur sa mise en œuvre:
http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf?=submit

EDIT 2:
Le support de module en clang a été documenté ici:
http://clang.llvm.org/docs/Modules.html

EDIT 3:
Les modules sont désormais également pris en charge dans le compilateur C ++ de Microsoft: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

  1. Parce que c’est un très grand changement conceptuel.
  2. Il n’y a pas vraiment besoin de cela car la séparation des sources en h / cpp fait l’affaire
  3. Parce que C ++ ne définit pas comment les bibliothèques de “modules” sont construites. Cela laisse au développeur du compilateur et à l’éditeur de liens.
  4. Les “modules” dépendent parfois assez de la plate-forme, par exemple les DLL sont très différents des objects partagés. Il n’est donc pas si simple de fusionner ces concepts.