Questo è iniziato come una domanda SO ma mi sono reso conto che è piuttosto non convenzionale e basato sulla descrizione attuale sui siti Web, potrebbe essere più adatto ai programmatori. Visto che la domanda ha molto peso concettuale.
Ho imparato il clanging LibTooling ed è uno strumento molto potente in grado di esporre l'intero "grintoso" del codice in un modo amichevole, cioè in modo semantico , e non indovinando neanche. Se clang può compilare il tuo codice, allora clang è certo della semantica di ogni singolo carattere all'interno di quel codice.
Ora permettimi di fare un passo indietro per un momento.
Ci sono molti problemi pratici che sorgono quando ci si impegna nella metaprogrammazione dei template C ++ (e specialmente quando si avventurano oltre i template nel territorio di macro intelligenti sebbene terrificanti). Ad essere sincero, per molti programmatori, me compreso, anche molti degli usi ordinari dei template sono in qualche modo terrificanti.
Immagino che un buon esempio sarebbe stringhe in fase di compilazione . Questa è una domanda che ha più di un anno ormai, ma è chiaro che il C ++ in questo momento non lo rende facile per i semplici mortali. Mentre guardare queste opzioni non è abbastanza per indurre la nausea per me, mi lascia comunque incerto sul fatto di essere in grado di produrre un codice macchina magico e massimamente efficiente per adattarsi a qualsiasi fantastica applicazione che ho per il mio software.
Voglio dire, ammettiamolo, gente, le stringhe sono piuttosto semplici ed elementari. Alcuni di noi vogliono solo un modo conveniente per emettere codice macchina che ha "stringhe" di determinate stringhe molto più di quanto otteniamo quando lo codifichiamo in modo semplice. Nel nostro codice C ++.
Immettere clang e LibTooling, che espone l'albero di sintassi astratto (AST) del codice sorgente e consente a una semplice applicazione C ++ personalizzata di manipolare correttamente e in modo affidabile il codice sorgente grezzo (usando Rewriter
) insieme a un ricco modello semantico orientato agli oggetti di tutto ciò che si trova nell'AST. Gestisce molte cose. Conosce le macro espansioni e ti consente di seguire quelle catene. Sì, sto parlando della trasformazione o della traduzione del codice sorgente-sorgente.
La mia tesi fondamentale qui è che clang ora ci consente di creare file eseguibili che possono funzionare da soli come stadi del preprocessore personalizzato ideale per il nostro software C ++ e che possiamo implementare queste fasi di metaprogrammazione con C ++. Siamo semplicemente limitati dal fatto che questa fase deve prendere input che è un codice C ++ valido e produrre come output un codice C ++ più valido. Inoltre qualunque altra limitazione si applichi al tuo sistema di compilazione.
L'input deve essere almeno molto vicino al codice C ++ valido perché, dopo tutto, clang è il front-end del compilatore e stiamo solo cercando e siamo creativi con la sua API. Non so se ci siano disposizioni per poter definire una nuova sintassi da usare, ma chiaramente dobbiamo sviluppare i modi per analizzarla correttamente e aggiungerla al progetto clang per farlo. Aspettarsi di più significa avere qualcosa nel progetto clang che è fuori portata.
Non è un problema. Immagino che alcune funzioni macro no-op possano gestire questo compito.
Un altro modo di vedere quello che sto descrivendo è implementare costrutti di metaprogrammazione usando il runtime C ++ manipolando l'AST del nostro codice sorgente (grazie a clang e alla sua API) invece di implementarli usando gli strumenti più limitati disponibili nel linguaggio stesso. Ciò ha anche chiari vantaggi in termini di prestazioni della compilazione (le intestazioni pesanti del modello rallentano la compilazione in proporzione alla frequenza con cui li usi. Molte cose compilate vengono quindi accuratamente abbinate e gettate via dal linker).
Questo, tuttavia, comporta il costo di introdurre uno o due passaggi aggiuntivi nel processo di compilazione e anche la necessità di scrivere un software (certo) un po 'più dettagliato (ma almeno è un runtime semplice C ++) come parte del nostro strumento .
Non è l'intero quadro. Sono abbastanza certo che esiste uno spazio molto più ampio di funzionalità che si può ottenere dalla generazione di codice che è estremamente difficile o impossibile con le funzionalità del linguaggio di base. In C ++ puoi scrivere un modello o una macro o una combinazione folle di entrambi, ma in uno strumento clang puoi modificare classi e funzioni in QUALSIASI modo che puoi ottenere con C ++, in fase di esecuzione , pur avendo pieno accesso al contenuto semantico, oltre a template e macro e tutto il resto.
Quindi, mi chiedo perché tutti non lo stiano già facendo. È che questa funzionalità di clang è così nuova e nessuno ha familiarità con l'enorme gerarchia di classi dell'AST di clang? Non può essere.
Forse sto solo sottovalutando un po 'la difficoltà di questo, ma fare "manipolazione di stringhe in fase di compilazione" con uno strumento clang è quasi criminalmente semplice. È prolisso, ma è follemente semplice. Tutto ciò che serve sono un mucchio di funzioni macro no-op associate a std::string
operazioni reali reali . Il plug-in clang lo implementa recuperando tutte le chiamate macro no-op rilevanti ed esegue le operazioni con stringhe. Questo strumento viene quindi inserito come parte del processo di compilazione. Durante la compilazione, queste chiamate a funzioni macro non operative vengono automaticamente valutate nei loro risultati e quindi reinserite come semplici stringhe di compilazione nel programma. Il programma può quindi essere compilato come al solito. In effetti, questo programma risultante è anche molto più portatile di conseguenza, non richiede un nuovo compilatore di fantasia che supporti C ++ 11.