C'è un motivo per definire i tipi alias in qualsiasi programma

5

Ho iniziato a imparare c ++ per qualche tempo fa. È un grande argomento e non sono ancora molto abituato. Questa domanda è quindi posta più sulla curiosità, che su qualcos'altro. Nel libro che ho letto per imparare ora c'è una discussione sulla portabilità. Sono d'accordo sul fatto che la discussione giunga piuttosto a qualcuno all'inizio del periodo di apprendimento, ma durante la lettura sono arrivato a Pensare a qualcosa.

Quello che mi chiedo è: c'è mai un motivo per definire un tipo personalizzato da usare al posto dei tipi di base incorporati? Ad esempio, sarebbe utile definire un tipo int_c come in "int custom"? La ragione per cui penso a questo è dato dal fatto che alcuni codici possono essere compilati ad esempio sia un compilatore a 32 bit che un compilatore a 64 bit. Sembra come se fosse più semplice, perché se cambi piattaforma e tutti gli interi sono definiti come int_c invece di int , poiché quest'ultimo richiederebbe il cambio di tipo in ogni posizione viene usato un int?

Tuttavia, so anche che <cstdint> contiene le definizioni di diverso intero come int64_t . Tuttavia non ho sentito di un'intestazione con tipi di punti mobili.

Quindi per concludere: c'è un motivo per definire interi o float personalizzati come int_c o double_c o in caso contrario qual è il miglior apporach?

    
posta patrik 30.07.2014 - 19:19
fonte

1 risposta

7

A volte c'è un motivo per farlo, tuttavia <stdint.h> (in C99) o <cstdint> (in C ++ 03 o beter) li rende meno ovvi.

Innanzitutto, c'è un problema di leggibilità. Se definisci

typedef unsigned myhash_t;

e in seguito usa sempre myhash_t per i numeri che sono in realtà degli hash, faciliti la comprensione del tuo codice. Ciò non aiuta molto contro i propri errori (ad esempio dimenticando di dichiarare un parametro come myhash_t anche se si tratta di un hash) ma migliora la leggibilità.

Quindi con <stdint.h> (ecc.) hai molti nuovi tipi integrali (molti dei quali sono sinonimi specifici del sistema per esempio int e long ), come int64_t (un int firmato di esattamente 64 bit), uintptr_t (un numero intero senza segno con le stesse dimensioni dei puntatori), int_fast8t (un tipo integrale, che viene calcolato rapidamente, di almeno 8 bit, ma potrebbe essere 16 bit se corrono più velocemente, ecc. ...)

Finalmente, puoi piazzare trucchi con il preprocessore con ad es. #if combinato a tale typedef -s. Ad esempio, potresti definire una codifica a colori con 3 componenti RGB (o 4, RGBA) di

 typedef uint8_t color_t;

ma alcuni trucchi del preprocessore potrebbero renderlo un uint16_t ....

FWIW, Ocaml e Ada stanno facendo meglio del C ++ in questo senso. Sono in grado di definire tipi interi privati (vedi ad esempio §7.9.2 in Ocaml ref .), In cui l'aritmetica è vietata (se non esplicitamente consentito). In C ++ potresti avere class MyHiddenInt { int x; /*etc*/ }; ma potrebbe essere rappresentato e gestito in modo diverso (cioè producendo un codice macchina meno efficiente) di qualche int . I dettagli sono ovviamente ABI specifici. Su Linux / x86-64 con ottimizzazione -O2 il codice generato GCC 4.9 (ad esempio per un'aggiunta) sarebbe lo stesso.

A volte questi interi privati hanno senso. Per esempio su Unix e Posix i descrittori di file sono int -s ma fare qualsiasi aritmetica su di essi è privo di senso. (similmente per myhash_t probabilmente, ma non puoi esprimere quel vincolo in C ++).

Per i numeri a virgola mobile è ancora più importante. Su alcuni processori (ad esempio alcuni GPGPU), l'aritmetica di precisione double è talmente lenta da evitarlo. Sul nostro laptop & dekstop PC, è il contrario: quasi sempre si usa double (che oggi significa IEEE754 a 64 bit in virgola mobile) e si usa float (o short ) solo per spremere il consumo di memoria. Queste scelte sono davvero specifiche del processore (non le stesse su un tablet o un supercomputer).

Potresti andare ancora oltre, e avere un'analisi di tipo che tenga conto delle dimensioni fisiche. Quindi proibisci (al momento della compilazione) di aggiungere chilogrammi con ampere o watt e che il prodotto di una velocità (in metri al secondo) con un tempo (in secondi) è una lunghezza (in metri) che non dovrebbe essere accettabile come file descrittore o hash.

Leggi informazioni su tipi di dati astratti .

    
risposta data 30.07.2014 - 19:26
fonte

Leggi altre domande sui tag