Moduli C ++: perché sono stati rimossi da C ++ 0x? Torneranno più tardi?

Ho appena scoperto questa vecchia bozza di C ++ 0x sui moduli in C ++ 0x.

L’idea era di uscire dall’attuale sistema .h / .cpp scrivendo solo i file .cpp che avrebbero poi generato i file del modulo durante la compilazione, che a loro volta sarebbero stati usati dagli altri file .cpp.

Questa sembra davvero una grande funzionalità.

Ma la mia domanda è: perché lo hanno rimosso da C ++ 0x? Era a causa di troppe difficoltà tecniche? Mancanza di tempo? E pensi che prenderanno in considerazione la possibilità di lavorarci per un’ulteriore versione di C ++?

Da State of C ++ Evolution (Post San Francisco 2008) , la proposta Modules è stata classificata come “Intestazione per un TR separato:”

Questi argomenti sono ritenuti troppo importanti per aspettare un altro standard dopo C ++ 0x prima di essere pubblicati, ma troppo sperimentali per essere finalizzati in tempo per il prossimo Standard. Pertanto, queste funzionalità verranno fornite da una relazione tecnica il prima ansible.

La proposta dei moduli non era pronta e in attesa che avrebbe ritardato la finitura dello standard C ++ 0x. Non è stato veramente rimosso, non è stato mai incorporato nel documento di lavoro.

Bozza di moduli C ++ (Specifiche tecniche dopo C ++ 17)

Una bozza e diverse revisioni aggiornate per le specifiche del modulo C / C ++ sono state pubblicate da WG21 su open-std.org. Collegherò solo ai documenti più recenti qui:

  • Working Draft, Estensioni in C ++ per i moduli N4610 (ottobre 2016).
  • Quarta revisione pubblicata come P0142R0 (marzo 2016).
  • Wording per moduli pubblicati come P0143R2 (marzo 2016).
  • Il team clang ha pubblicato una seconda revisione delle loro modifiche: P0273R1 (ottobre 2016).

I seguenti post del blog contengono un riepilogo degli incontri sugli standard e in particolare un riepilogo dello stato corrente della bozza dei moduli:

  • Rapporto di viaggio: incontro degli standard C ++ a Lenexa (maggio 2015).
  • Rapporto di viaggio: incontro degli standard C ++ a Kona (ottobre 2015).
  • Rapporto di viaggio: incontro degli standard C ++ a Jacksonville (febbraio 2016).
  • Rapporto di viaggio: incontro degli standard C ++ a Oulu (giugno 2016).
  • Rapporto di viaggio: incontro degli standard C ++ a Issaquah (novembre 2016).

Aggiornamento: come spiegato nel rapporto del viaggio di Kona che ho collegato sopra, attualmente ci sono due proposte in competizione, una di Microsoft e una di Clang. La soluzione proposta da Microsoft non consente di esportare macro, mentre la soluzione del team Clang supporta l’esportazione di macro. Finora solo Microsoft ha presentato formalmente una bozza per una specifica del modulo.

Specifiche del modulo come proposto da Microsoft

Ecco una rapida panoramica dei concetti più importanti contenuti in questa proposta. Essendo una bozza questo potrebbe ancora cambiare. Il nuovo standard dei moduli comprenderà tra l’altro:

Una parola chiave module per dichiarare un modulo, più file possono dichiararlo per creare un modulo (ma per ogni modulo solo una unità di compilazione può contenere una sezione export {} ):

 module M; 

Una parola chiave di importazione per importare moduli, invece di import potrebbe anche essere deciso di utilizzare l’ using module , quindi una nuova parola chiave di importazione potrebbe essere evitata.

 import std.io; import module.submodule; 

Una syntax di export , che definisce le dichiarazioni pubbliche che fanno parte di questo modulo, le dichiarazioni senza interfaccia che non dovrebbero essere esportate come parte del modulo saranno definite al di fuori del blocco di esportazione. Le dichiarazioni possono essere qualsiasi tipo di dichiarazione in C / C ++, cioè non solo funzioni, ma anche variabili, strutture, modelli, spazi dei nomi e classi:

 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 importante cambiamento di moduli sarà che le macro e le definizioni del preprocessore saranno locali ai moduli e non saranno esportate. Quindi le macro non hanno alcun impatto sui moduli importati:

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

È importante notare che sia l’attuale sistema di preprocessore che i moduli saranno in grado di coesistere e le intestazioni possono ancora essere utilizzate, ad esempio per includere macro.

Per informazioni più dettagliate suggerisco di leggere la bozza.

Moduli Clang

Clang ha lavorato a un’implementazione di moduli che può essere trovata nella pagina dei moduli clang . Tuttavia clang non implementa attualmente una syntax concreta per i moduli, cioè nessuna delle syntax sopra menzionata è stata implementata da Clang. Per spiegare questo la pagina contiene la seguente dichiarazione:

Al momento, non esiste una syntax C o C ++ per le dichiarazioni di importazione. Clang seguirà la proposta dei moduli nel comitato C ++. Vedi la sezione Include come importazioni per vedere come i moduli vengono importati oggi.

La parte principale attualmente implementata da Clang è il “Module Map Language” che consente di scrivere le mappe dei moduli per il codice esistente che utilizza ancora i file di intestazione.

Macro esportazioni da moduli

Come accennato in precedenza, non è ancora chiaro se le esportazioni di macro saranno parte dei moduli finali TS . In P0273R1 è stata proposta la seguente syntax per l’esportazione di macro:

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

Clang è il primo compilatore che inizia a lavorare sui moduli ancor prima che la standardizzazione sia completa. Non c’è ancora molta documentazione, ma il codice di esempio potrebbe essere trovato qui:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/

Alcuni commenti di Douglas Gregor (lo sviluppatore che li implementa):
http://clang-developers.42468.n3.nabble.com/C-modules-td3619936.html

In teoria, puoi definire un gruppo di macro helper come begin_module, end_module, import_module per proteggerti da eventuali modifiche alla syntax che verranno in futuro.

MODIFICA 1:
Douglas Gregor ha rilasciato una presentazione sulla sua implementazione:
http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf?=submit

MODIFICA 2:
Il supporto del modulo in clang è stato documentato qui:
http://clang.llvm.org/docs/Modules.html

MODIFICA 3:
I moduli sono ora supportati anche nel compilatore C ++ di Microsoft: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

  1. Perché è un grande cambiamento concettuale.
  2. Non ce n’è davvero bisogno, poiché la separazione delle fonti in h / cpp fa il lavoro
  3. Perché il C ++ non definisce come vengono costruite le librerie “moduli”. Lo lascia allo sviluppatore del compilatore e al linker.
  4. I “moduli” sono talvolta piuttosto dipendenti dalla piattaforma, ad esempio DLL piuttosto diversi dagli oggetti condivisi. Quindi non è così semplice fondersi tra questi concetti.