In informatica la sicurezza rispetto al tipo (in inglese type safety) è la misura con cui un linguaggio di programmazione previene o avvisa rispetto agli errori di tipo.
Un errore di tipo è un comportamento errato o non desiderabile del programma causato da una discrepanza tra diversi tipi di dato riguardo alle costanti, variabili e metodi (funzioni) del programma.
I possibili errori di tipo sono i seguenti:
Un linguaggio è considerato essere type safe se tutti gli errori di tipo vengono rivelati sempre, a compile-time (meglio) o almeno a run-time tramite adeguati controlli.
A volte la type safety è considerata alternativamente come una proprietà di un programma piuttosto che del linguaggio in cui il programma è stato scritto; ovvero, alcuni linguaggi hanno delle caratteristiche di type safeness che possono essere eluse dai programmatori che adottano pratiche poco type safe.
Il controllo dei tipi e del loro corretto utilizzo può quindi avvenire in compilazione (compile-time) o in esecuzione (run-time):
La type safety è collegata alla memory safety, una restrizione della possibilità di copiare arbitrariamente dei bit di memoria da una locazione ad un'altra. Per esempio, il seguente codice C++:
#include <iostream>
using namespace std;
int main(){
char x = 'a';
void* p = (void*) &x;
double* d = (double*) p;
cout << x << endl << *d << endl;
// output:
// a
// 2.8477e-306
return 0;
}
Fa un'evidente violazione di tipo, in quanto crea inizialmente una variabile char, creando poi un puntatore vuoto che ci punta e facendo un cast a double, cambia il tipo del puntatore. Successivamente, ci accede e ne stampa il valore. Come prevedibile, l'output non ha senso (e varia per ogni esecuzione) in quanto una variabile di tipo char è allocata come 1 byte sullo stack mentre una variabile di tipo double necessita di 8 byte, oltre ad essere di tipo non compatibile.
Per questo motivo, è considerato indispensabile per un linguaggio avere dei meccanismi di gestione della memoria automatici, come il Garbage Collector o altri meccanismi che eseguono a compile-time come ARC per Objective-C, per evitare l'accesso a variabili già deallocate o accessi tipo quello visto prima.
I linguaggi si dividono quindi solitamente in tre categorie:
Essere un linguaggio sicuro o safe impone quindi maggiori vincoli e maggiore sicurezza nella creazione del programma. Di contro però, ci possono essere problematiche legate all'efficienza (dovendo aumentare i controlli a run-time) e all'impossibilità di gestire l'allocazione della memoria e il momento di distruzione degli oggetti, che (per certa categoria di applicazioni) possono finire col saturare l'heap.