Tiny C Compiler
# Tiny C Compiler

Tiny C Compiler (noto anche come TCC, tCc o TinyCC) è un compilatore C per piattaforme x86 e ARM creato da Fabrice Bellard e distribuito sotto licenza LGPL. È un compilatore minimale, che si presta bene all'uso su sistemi lenti e con poche risorse di memoria e archiviazione. Nato per sistemi Unix-like, con la versione 0.9.23 (17 giugno 2005) gli è stato aggiunto il supporto a Windows.

Secondo la documentazione, TCC implementa interamente lo standard ANSI C (C89/C90), buona parte dello standard ISO C99 e molte delle estensioni GNU C, tra le quali l'inserimento di assembly inline.

## Caratteristiche

TCC ha alcune caratteristiche peculiari che lo differenziano da molti compilatori C:

* Ha dimensioni contenute (circa 100 KB per l'eseguibile del compilatore x86) e un'impronta di memoria ridotta, al punto da poter essere usato su un singolo floppy disk da 1.44 M, come ad esempio un disco di ripristino.
* TCC è concepito per generare codice nativo x86, x86-64 e ARM molto rapidamente: secondo Bellard, compilazione, assemblaggio e linking sono circa nove volte più veloci di GCC.
* TCC ha alcune funzionalità aggiuntive che lo rendono pratico, come ad esempio il bound check.
* TCC consente di eseguire direttamente i programmi a compile time grazie ad uno switch, consentendo di eseguire script in C nelle shell che supportano la direttiva shebang.
* La libreria libtcc.so consente di creare funzioni C a runtime all'interno di programmi C o C++: il codice, contenuto in una stringa, viene compilato tramite le funzioni fornite dalla libreria e il codice macchina corrispondente viene caricato in una porzione di memoria con permessi di esecuzione, della quale viene restituito un puntatore che consente di invocare la funzione.

## Performance del codice generato

TCC ha tempi di compilazione molto rapidi, tuttavia questo comporta un compromesso con l'efficienza del codice generato da esso. Il compilatore esegue un numero limitato di ottimizzazioni, come constant folding per tutte le operazioni, ottimizzazione di moltiplicazioni e divisioni tramite shift aritmetico quando possibile, ottimizzazione degli operatori di confronto tramite l'uso di una specifica cache, e una semplice register allocation che consente di risparmiare cicli di save/load all'interno di una singola istruzione ad alto livello.

In generale TCC punta maggiormente a compattezza e velocità piuttosto che all'ottimizzazione, generando il codice in un unico passaggio e senza eseguire molte delle ottimizzazioni praticate comunemente dai principali compilatori ottimizzanti. In particolare, TCC compila ogni istruzione individualmente, riportando i valori dei registri sullo stack al termine di ognuna e richiedendo una nuova lettura degli stessi se l'istruzione successiva li riutilizza. TCC inoltre non usa tutti i registri disponibili, ad esempio nell'architettura x86 non impiega mai i registri ebx, esi e edi, perché devono essere preservati dalle chiamate di funzione.

In un benchmark effettuato usando una versione modificata di TCC, capace di compilare GCC, l'esecuzione di cc1 (il compilatore C di GCC) su sé stesso, usando un livello di ottimizzazione -O1 o equivalente, ha richiesto 518 secondi quando compilato con GCC 3.4.2, 558 secondi con GCC 2.95.3, 545 con il compilatore C Microsoft e 1145 con TCC.

## Impiego

Tra gli impiegi di TCC:

* TCCBOOT, che impiega TCC per caricare ed eseguire il kernel Linux da sorgenti. È una sorta di bootloader che legge i sorgenti da disco, scrive le corrispondenti istruzioni macchina in memoria e le esegue.
* TCC è stato usato per mostrare un meccanismo di difesa rispetto alla vulnerabilità Trusting Trust.
* TCC è stato impiegato per compilare GCC, anche se allo scopo sono necessarie alcune patch.
* Cinpy è una libreria Python che consente di implementare funzioni C nei moduli Python, che vengono compilate a runtime con TCC e rese richiamabili dal Python tramite la libreria ctypes.

## Storia

TCC è l'evoluzione di Obfuscated Tiny C Compiler (OTCC), un programma scritto da Bellard con il quale ha vinto l'International Obfuscated C Code Contest (IOCCC) del 2001 come Best abuse of the rules. Bellard ha in seguito esteso e de-offuscato il programma, ottenendo TCC.

## Stato del progetto

TCC ha una mailing list attiva e la versione del software di Bellard è disponibile su un repository Git. Tuttavia, lo sviluppo di TCC è discontinuo, per via dell'impegno di Bellard in altri progetti.

Rob Landley ha creato un fork di TCC per includere svariate patch di terze parti, tramite Mercurial. Il progetto è stato abbandonato il 4 ottobre 2004 ed è rinato in un fork il 27 ottobre 2007 fino al 5 settembre 2008. Da allora, TCC ha ricevuto solo due aggiornamenti, il 20 maggio 2009 e il 15 febbraio 2013.

Altri programmatori hanno distribuito patch o versioni estese di TCC, come la collezione di patch di terze parti di Dave Dodge, le patch dei progetti Debian e kfreebsd, e di grischka. Il repository pubblico di grischka contiene un branch con contributi più recenti e alcune funzionalità aggiuntive.

