Typedef
# Typedef

typedef è una parola chiave dei linguaggi di programmazione C e C++. Lo scopo della typedef è quello di assegnare dei nomi alternativi a dei tipi di dato esistenti, solitamente a quelli la cui dichiarazione standard è troppo ingombrante, magari confusionale, oppure per rendere il codice riutilizzabile più facilmente tra un'implementazione e un'altra.

Per le convenzioni del C (delle librerie standard), i tipi dichiarati con typedef finiscono con la stringa "_t" (per esempio, size_t, time_t).

## Esempi di utilizzo

### Per indicare cosa rappresenta una variabile

Una typedef può essere usata per indicare come una variabile rappresenta qualcosa, ad esempio un'unità di misura:

Ora si consideri:

Entrambe le sezioni di codice implementano la stessa operazione. Ciononostante, l'uso della typedef nel secondo esempio rende più chiaro il fatto che, nonostante le due variabili sono rappresentate dallo stesso tipo di dato (int), le informazioni in esse contenute sono logicamente incompatibili. La dichiarazione in congratulate di your_score indica al programmatore che current_speed (o qualunque altra variabile non dichiarata come points) non dovrebbe essere passata come argomento. Questo non sarebbe stato così visibile se entrambe fossero state dichiarate come interi. Si noti che l'indicazione è utile soltanto per i programmatori; Il compilatore C/C++ considera entrambe le variabili come intere, e non segnalerà alcuna incompatibilità se si passasse current_speed come argomento alla funzione congratulate.

### Semplificare una dichiarazione

Una typedef può essere utilizzata per semplificare la dichiarazione di un tipo di dato composto (struct, union) oppure di un puntatore.

Sopra è stato definito il tipo di dato struct var. Per dichiarare una variabile di questo tipo, in C, è richiesto l'uso della parola chiave struct (questo non vale per il C++):

Una typedef può essere utilizzata per eliminare la necessità di ripetere la parola struct. Per esempio con:

ora possiamo creare una variabile di questo tipo con:

Si noti che la definizione della struttura e la typedef possono essere combinate in una singola istruzione:

Nel C++, in contrasto con il C, le parole chiave struct, class, e enum sono opzionali nelle dichiarazioni delle variabili che sono separate dalle definizioni.

Così, var può essere utilizzata ogniqualvolta newtype può essere usata. In ogni modo, non è vero il contrario. Per esempio, il metodo costruttore per var non può essere chiamato newtype.

### Utilizzare typedef con puntatori

Le typedef possono inoltre semplificare le dichiarazioni per i tipi puntatore. Si consideri questo:

Nel C, è possibile dichiarare più variabili dello stesso tipo in una singola istruzione, pure mischiando puntatori e non puntatori. Ad ogni modo, è necessario apporre un asterisco davanti ad ogni variabile per renderla un puntatore.

Un programmatore probabilmente presupporrebbe che errptr fosse in realtà di tipo Node *, ma per un errore di battitura errptr è di tipo Node. Ciò porterà ad un errore di sintassi.

Definendo una typedef per Node *, si è sicuri che tutte le variabili saranno di tipo puntatore.

### Utilizzare il typedef con cast di tipo

Si crea una typedef usando la sintassi della dichiarazione di tipo, ma può essere usata come se fosse stata creata usando la sintassi del cast di tipo. Ad esempio, in ciascuna riga di codice dopo la prima riga di:

funcptr viene usato nella parte sinistra per dichiarare una variabile e nella parte destra dell'assegnamento per convertire un valore. Quindi, le typedef possono essere usate dai programmatori che non vogliono capire come convertire la sintassi dichiarativa in sintassi di cast.

Nota che, senza typedef, in genere non è possibile usare sintassi dichiarativa e di cast in maniera intercambiabile. Ad esempio:

## Preoccupazioni sull'utilizzo

Alcuni si oppongono all'uso intensivo delle typedef. La ragione principale è il fatto che i typedef nascondono il vero tipo di dato della variabile. Per esempio, Greg Kroah-Hartman, un hacker esperto e sviluppatore del kernel Linux, scoraggia il loro uso per tutto ad eccezione della dichiarazione del prototipo di una funzione. Sostiene che questa pratica non solo offusca il codice senza alcun bisogno, ma può anche causare confusione nel programmatore che fa accidentalmente cattivo uso di grosse strutture dati pensando che esse siano di tipo elementare.

Altri sostengono che l'utilizzo delle typedef renda più facile la revisione del codice. Il K&R dichiara che ci sono due ragioni per l'utilizzo delle typedef. La prima, rendono il codice più portabile. Invece di dover cambiare un tipo di dato ogniqualvolta esso compare nell'intero sorgente, si cambia soltanto una typedef. La seconda, le typedef possono rendere più facile da comprendere una dichiarazione complessa.

### Utilizzo nel C++

Nel C++ i nomi di tipo possono essere molto complicati e typedef fornisce un meccanismo per assegnare un nome semplice al tipo.

e

**Uso con template nel C++**

Non c'è un modo diretto per avere una typedef in un template in C++. Ad esempio, per far sì che value_t<T> rappresenti std::pair<std::string, T> per ogni class T non è possibile usare:

Ad ogni modo, se si vuole accettare value_t<T>::foo, o qualcosa di simile, anziché value_t<T>, allora si può ottenere il risultato desiderato con una typedef all'interno di una classe o struttura contenuta in un template:

Dal C++11 è possibile utilizzare un'alias declaration utilizzando la keyword using per ottenere il risultato voluto:

## Altri linguaggi

In svariati linguaggi di programmazione funzionale, come l'Haskell, Miranda, OCaml, ecc., è possibile definire i cosiddetti type synonyms, sinonimi di tipo, che corrispondono alle typedef in C. Un esempio scritto in Haskell:

Questo esempio definisce un sinonimo di tipo chiamato "PairOfInts" che ha lo stesso significato di una coppia di interi.

Il C# include una caratteristica simile al typedef del C: lo svantaggio è però che deve essere dichiarata per ogni file separatamente.

