Dopo sei mesi di sviluppo, è stata presentata la release del progetto LLVM 18.1.0 - uno strumento compatibile con GCC (compilatori, ottimizzatori e generatori di codice) che compila programmi in un codice intermedio di istruzioni virtuali simili a RISC (una macchina virtuale a basso livello con un sistema multi-livello di ottimizzazioni). Il pseudocodice generato può essere trasformato mediante un compilatore JIT in istruzioni macchina al momento dell'esecuzione del programma.
A partire dal ramo 18.x, il progetto ha adottato un nuovo schema per la numerazione delle versioni. Analogamente ai progetti GCC e GDB, la release zero («N.0») è ora utilizzata nel processo di sviluppo, mentre la prima versione stabile è contrassegnata con il numero «N.1». Questa modifica consente di separare le versioni compilate dal ramo in fase di sviluppo (mainline) da quelle con le release finali. Ad esempio, durante la preparazione dell'attuale release, lo sviluppo è avvenuto utilizzando il ramo instabile LLVM 18.0, e la prima release stabile è stata pubblicata con il numero 18.1.0. In futuro, se necessario, possono essere rilasciate versioni correttive ogni due settimane con i numeri 18.1.1, 18.1.2, e così via. In caso di modifiche nel ramo attuale che violano l'ABI, l'aggiornamento sarà numerato modificando il secondo numero di versione (ossia 18.2.0).
Miglioramenti principali in Clang 18:
- Cambiamenti relativi al linguaggio C:
- Le strutture, le unioni e gli array con il modificatore «const» possono ora essere utilizzati come espressioni costanti, analogamente a quanto avviene in GCC.
- Le enumerazioni (enum) ora vengono riflesse nei metadati TBAA (Type Based Alias Analysis) nel loro tipo intero originale, invece di essere trattate come tipo «char».
- È stata aggiunta la supporto per l'attributo «counted_by», che permette di specificare un campo in una struttura con un array flessibile, definendo il numero di elementi nell'array flessibile. Questo attributo può essere usato in clang per migliorare l'efficienza dei controlli sugli overflow dei buffer.
- Funzionalità definite nel futuro standard C23:
- È stata aggiunta la supporto per i flag «-std=c23» e «-std=gnu23», oltre al valore «202311L» per la macro «__STDC_VERSION__», che definisce lo standard C23 e le estensioni GNU C23.
- È stata aggiunta la supporto per l'espressione «requires c23» per legare i moduli al supporto dello standard C23.
- È stata implementata la supporto per l'output di tipo nella definizione degli oggetti, permettendo l'uso del modificatore «auto» per inferire il tipo delle variabili basato sul tipo dell'espressione per la loro inizializzazione. Ad esempio: «auto y = cos(x);».
- È stata aggiunta la supporto per l'intestazione con macro per il controllo dei calcoli interi.
- È permesso posizionare etichette in qualsiasi punto all'interno di espressioni composte.
- Nella compilazione in modalità C23, è stata interrotta la supporto per il codice dei trigrafi, sequenze di tre caratteri ASCII trattati come un carattere, ad esempio, la sequenza «??=» poteva essere utilizzata al posto di «#». Dopo l'introduzione di Unicode, la supporto per i trigrafi ha perso significato.
- Funzionalità legate allo standard C++20: è stata implementata una funzionalità sperimentale per l'uso in template di ulteriori tipi di argomenti che non siano tipi, ad esempio, è permesso specificare valori a virgola mobile, puntatori e riferimenti a suboggetti.
- Funzionalità legate allo standard C++23: è stata aggiunta la supporto sperimentale per il meccanismo «Deducing this», che permette l'uso in template di parametri con il modificatore «this», consentendo a una funzione di classe di determinare la categoria dell'espressione (ad esempio, se è una costante) per la quale questa funzione è stata invocata.
- Funzionalità legate al futuro standard C++2c (C++26):
- È stata aggiunta la possibilità di utilizzare più variabili di riempimento con nome «_» in un singolo ambito, ad esempio, ora le seguenti costruzioni sono corrette: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // precedentemente emesso un avviso in modalità -Wunused }
- È stata fornita la possibilità di utilizzare letterali di stringa in un contesto in cui non sono utilizzati per inizializzare un array di caratteri e non vengono inclusi nel codice risultante, ma sono impiegati solo durante la compilazione per messaggi diagnostici e pre-processing, ad esempio, come parametri per direttive e attributi _Pragma, asm, extern, static_assert, [[deprecated]] e [[nodiscard]].
- È stato retrocesso a obsoleto l'esecuzione di conversioni implicite di valori enumerati in calcoli aritmetici. int main() { enum E1 { e }; enum E2 { f }; bool b = e
Fonte: opennet.ru
