Cyclone è un linguaggio di programmazione rilasciato l'8 maggio 2006 ed inteso a diventare un dialetto sicuro del C. Infatti a differenza di quest'ultimo riesce a evitare i buffer overflows e altre vulnerabilità endemiche del linguaggio C, senza perdere la potenza e la convenienza della programmazione strutturata.
Lo sviluppo di Cyclone è iniziato come un progetto congiunto di gruppo tra AT & T Labs e Greg Morrisett della Cornell University, nel 2001.
Caratteristiche del Linguaggio Cyclone riesce ad evitare alcuni dei problemi comuni di C, pur mantenendo il suo aspetto e le prestazioni. A tal fine, Cyclone pone i seguenti limiti sui programmi: Controlli NULL per evitare errori di segmentazione Limite sull'uso dei puntatori aritmetici Obbligo di inizializzazione degli array prima dell'uso Analisi di regione dei Dangling pointer e uso del free() limitati Consentiti solo casting e union "sicuri" goto disabilitati in certi ambiti Etichette switch disabilitate in casi di disambiguità Obbligo di restituzione dei puntatori con return setjmp e longjmp non supportati Al fine di mantenere i tool set che vengono usati dai programmatori del C, Cyclone fornisce le seguenti estensioni: Puntatori Never-NULL non richiedono i controlli NULL Supporto dei puntatori aritmetici da parte dei puntatori "FAT" e limiti di controllo sul Run-time Gestione della memoria supportata dalle Growable regions Garbage collection per allocazione dei valori heap Tagged unions supporta vari tipi di argomentazioni Le Injections contribuiscono l'automatizzazione dei delegati Funzioni void * rimpiazzate dal polimorfismo varargs implementati La gestione delle eccezioni sostituisce alcuni usi di setjmp e longjmp
Puntatori/Tipi di riferimento Cyclone implementa tre tipologie di riferimenti (seguendo la terminologia del C): * (puntatore comune) @ (puntatore never-NULL) ? (puntatore con supporto dei puntatori aritmetici e dei puntatori "Fat"). Questi nuovi tipi di puntatore sono stati introdotti per evitare i problemi più comuni. Prendiamo in considerazione la funzione foo, che indirizza il puntatore ad un intero: int foo(int *);Si suppone che l'ideatore del controllo foo non lo abbia inserito tramite controlli NULL per motivi di prestazioni, infatti chiamando foo(NULL); il codice si tradurrebbe in un segnale SIGSEGV. Per evitare tali problemi, Cyclone introduce il tipo di puntatore Never-Null @. Perciò la versione "sicura" di foo sarebbe: int foo(int @);In questo modo il compilatore comprende che foo è Never-NULL, evitando il suddetto comportamento indefinito. Il semplice scambio di * in @. permette al programmatore di evitare la scrittura dei controlli NULL. Questo limite in più, tuttavia, può essere un grande ostacolo per la maggior parte dei programmatori C, abituati a manipolare i puntatori direttamente con l'aritmetica, che porterebbero però a buffer overflows e altri errori simili. Per evitare ciò, il puntatore ? è designato per questa funzione. Anche se questo aggiungerebbe delle informazioni supplementari, migliora la sicurezza. Prendete per esempio una semplice funzione strlen, scritta in C: int strlen(const char *s) { int iter = 0; if (s == NULL) return 0; while (s[iter] != '\0') { iter++; } return iter; }Questa funzione presuppone che la stringa venga passata e terminata dal controllo NULL('\0'). Tuttavia risconteremmo errori nel passargli un array. Anche se questo errore non verrebbe riconosciuto in C, necessiterebbe dell'uso di strlen per correggere l'allocazione della memoria sulla stringa s, anche se queste funzioni non sono standard con ogni implementazione della versione ANSI C. Cyclone, infatti fa un uso di strlen non poi così diverso dal C: int strlen(const char ? s) { int iter, n = s.size; if (s == NULL) return 0; for (iter = 0; iter < n; iter++, s++) { if (*s == '\0') return iter; } return n; }Possiamo notare, nell'esecuzione del codice, i limiti di strlen nel passaggio della lunghezza della matrice. Il ? viene usato come puntatore indirizzato dal compilatore agli array, (il passaggio da * a ? pone un controllo sui limiti, infatti se avessimo usato il puntatore @ al posto di ? avremmo dovuto usare degli ulteriori controlli NULL e un casting da * a ? per ogni controllo NULL)
Puntatori dipendenti e analisi delle regioni Prendete in considerazione il seguente codice, scritto in C: char *itoa(int i) { char buf; sprintf(buf,"%d",i); return buf; }Il codice restituisce il valore di un oggetto allocato sullo stack della funzione itoa, che non sarà più disponibile dopo l'esecuzione delle istruzioni. Mentre GCC e altri compilatori mettono in guardia su questo codice, i seguente verrà compilato senza problemi: char *itoa(int i) { char buf, *z; sprintf(buf,"%d",i); z = buf; return z; }Cyclone, facendo un'analisi regionale, blocca i puntatori del come itoa, rendendo le variabili locali separate dal gruppo o da qualsiasi altra regione. In questo modo, inizializzando itoa, il compilatore vedrebbe che z punta allo stack locale, riscontrando degli errori.
Gestione manuale della memoria
Esempi Il migliore esempio del linguaggio Cyclone è il classico programma Hello world: #include <stdio.h> #include <core.h> using Core; int main(int argc, string_t ? args) { if (argc <= 1) { printf("Usage: hello-cyclone <name>\n"); return 1; } printf("Hello from Cyclone, %s\n", args); return 0;
Voci correlate C ML Rust (linguaggio di programmazione)
Collegamenti esterni
Documentazioni:
Categoria:C (famiglia di linguaggi)