No, vietare i tipi interi integrati sarebbe assurdo. Tuttavia, non dovrebbero subire abusi.
Se hai bisogno di un numero intero che sia esattamente N largo, usa std::intN_t
(o std::uintN_t
se hai bisogno di una versione unsigned
). Pensare a int
come numero intero a 32 bit e long long
come numero intero a 64 bit è semplicemente sbagliato. Potrebbe succedere di essere così nelle tue attuali piattaforme, ma questo si basa sul comportamento definito dall'implementazione.
L'uso di tipi interi a larghezza fissa è utile anche per interagire con altre tecnologie. Ad esempio, se alcune parti della tua applicazione sono scritte in Java e altre in C ++, probabilmente vorrai abbinare i tipi interi in modo da ottenere risultati coerenti. (Sappi comunque che l'overflow in Java ha semantica ben definita mentre l'overflow signed
in C ++ è un comportamento indefinito, quindi la coerenza è un obiettivo elevato.) Inoltre saranno preziosi quando scambieranno dati tra diversi host di calcolo.
Se non hai bisogno esattamente dei bit N , ma solo di un tipo sufficientemente largo , considera l'utilizzo di std::int_leastN_t
(ottimizzato per lo spazio) o std::int_fastN_t
(ottimizzato per la velocità). Ancora una volta, entrambe le famiglie hanno anche unsigned
controparti.
Quindi, quando usare i tipi predefiniti? Bene, dato che lo standard non specifica con precisione la loro larghezza, usali quando non ti preoccupi della larghezza effettiva del bit ma di altre caratteristiche.
Un char
è il più piccolo intero indirizzabile dall'hardware. Il linguaggio in realtà ti costringe a usarlo per l'aliasing della memoria arbitraria. È anche l'unico tipo valido per rappresentare stringhe di caratteri (strette).
Un int
di solito è il tipo più veloce che la macchina può gestire. Sarà sufficientemente ampio in modo che possa essere caricato e memorizzato con una singola istruzione (senza dover mascherare o spostare i bit) e abbastanza stretto in modo che possa essere utilizzato con (il più) efficiente istruzione hardware. Pertanto, int
è una scelta perfetta per il trasferimento di dati e l'esecuzione di operazioni aritmetiche quando l'overflow non è un problema. Ad esempio, il tipo di enumerazione di base predefinito è int
. Non cambiarlo in un intero a 32 bit solo perché è possibile. Inoltre, se hai un valore che può essere solo -1, 0 e 1, un int
è una scelta perfetta, a meno che non stai per archiviare enormi matrici di essi nel qual caso potresti voler utilizzare dati più compatti digitare al costo di dover pagare un prezzo più alto per l'accesso ai singoli elementi. Un caching più efficiente probabilmente pagherà per questi. Molte funzioni del sistema operativo sono anche definite in termini di int
. Sarebbe sciocco convertire i loro argomenti e risultati avanti e indietro. Tutto ciò che potrebbe fare è introdurre errori di overflow.
long
di solito è il tipo più largo che può essere gestito con istruzioni su macchina singola. Questo rende particolarmente interessante la percentuale diunsigned long
per gestire i dati grezzi e tutti i tipi di manipolazione di bit. Ad esempio, mi aspetto di vedere unsigned long
nell'implementazione di un vettore bit. Se il codice è scritto con attenzione, non importa quanto effettivamente sia effettivamente il tipo (perché il codice si adatterà automaticamente). Su piattaforme in cui la parola macchina nativa è a 32 bit, con l'array di supporto del vettore bit è una matrice di unsigned
Gli interi a 32 bit sono i più desiderabili perché sarebbe sciocco usare un tipo a 64 bit che deve essere caricato tramite costose istruzioni solo per spostare e mascherare di nuovo i bit non necessari di nuovo. D'altra parte, se la dimensione della parola nativa della piattaforma è di 64 bit, voglio un array di quel tipo perché significa che operazioni come "find first set" possono essere eseguite fino a due volte più velocemente. Quindi il "problema" del tipo di dati long
che stai descrivendo, che le sue dimensioni variano da piattaforma a piattaforma, in realtà è una funzione che può essere messa a buon uso. Diventa un problema solo se si pensa ai tipi predefiniti come tipi di una certa larghezza di bit, che semplicemente non lo sono.
char
, int
e long
sono tipi molto utili come descritto sopra. short
e long long
non sono altrettanto utili perché la loro semantica è molto meno chiara.