Vedo variabili definite con questo tipo ma non so da dove provenga, né qual è il suo scopo. Perché non utilizzare int o unsigned int? (E gli altri tipi "simili"? Void_t, ecc.).
Vedo variabili definite con questo tipo ma non so da dove provenga, né qual è il suo scopo. Perché non utilizzare int o unsigned int? (E gli altri tipi "simili"? Void_t, ecc.).
Risposte:
Da Wikipedia
I file di intestazione
stdlib.hestddef.hdefiniscono un tipo di dati chiamatosize_t1 che viene utilizzato per rappresentare la dimensione di un oggetto. Le funzioni di libreria che accettano dimensioni si aspettano che siano di tiposize_te l'operatore sizeof restituiscesize_t.Il tipo effettivo di
size_tdipende dalla piattaforma; un errore comune è presumere chesize_tsia uguale a unsigned int, che può portare a errori di programmazione, 2 in particolare quando le architetture a 64 bit diventano più diffuse.
I seguenti tipi e macro sono definiti nell'intestazione standard
stddef.h<Snip>
size_tche è il tipo intero senza segno del risultato dell'operatore sizeof
inte i unsigned inttipi sono 32 bit, mentre size_t è 64 bit.
Secondo size_t, la descrizione su en.cppreference.com size_t è definita nelle seguenti intestazioni:
std::size_t
...
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
size_t è il tipo intero senza segno del risultato dell'operatore sizeof (ISO C99 sezione 7.17.)
L' sizeofoperatore restituisce la dimensione (in byte) del suo operando, che può essere un'espressione o il nome tra parentesi di un tipo. La dimensione è determinata dal tipo di operando. Il risultato è un numero intero. Il valore del risultato è definito dall'implementazione e il suo tipo (un tipo intero senza segno) è size_t(ISO C99 Sezione 6.5.3.4.)
In pratica size_trappresenta il numero di byte che puoi indirizzare. Sulla maggior parte delle architetture moderne negli ultimi 10-15 anni sono stati 32 bit che hanno anche avuto le dimensioni di un int senza segno. Tuttavia ci stiamo spostando verso l'indirizzamento a 64 bit mentre uintmolto probabilmente rimarrà a 32 bit (la sua dimensione non è garantita nello standard c ++). Per rendere il tuo codice che dipende dalla dimensione della memoria portabile attraverso le architetture dovresti usare un file size_t. Ad esempio cose come le dimensioni degli array dovrebbero sempre usare size_t's. Se guardi i contenitori standard ::size()restituisce sempre un file size_t.
Si noti inoltre che Visual Studio ha un'opzione di compilazione che può verificare questi tipi di errori denominati "Rileva problemi di portabilità a 64 bit".
In questo modo sai sempre qual è la taglia, perché un tipo specifico è dedicato alle taglie. La stessa domanda mostra che può essere un problema: è un into uno unsigned int? Inoltre, qual è la grandezza ( short, int,long , etc.)?
Poiché è stato assegnato un tipo specifico, non devi preoccuparti della lunghezza o della firma.
La definizione effettiva può essere trovata nella libreria di riferimento C ++ , che dice:
Genere:
size_t(tipo integrale senza segno)Intestazione:
<cstring>
size_tcorrisponde al tipo di dati integrale restituito dall'operatore del linguaggiosizeofed è definito nel file<cstring>file di intestazione (tra gli altri) come tipo integrale senza segno.In
<cstring>, è usato come il tipo di parametronumnelle funzionimemchr,memcmp,memcpy,memmove,memset,strncat,strncmp,strncpyestrxfrm, che in ogni caso è utilizzato per specificare il numero massimo di byte o caratteri la funzione deve incidere.È anche usato come tipo cambio
strcspn,strlen,strspnestrxfrmper le dimensioni e lunghezze ritorno.
size_t dovrebbe essere definito nelle intestazioni della libreria standard. Nella mia esperienza, di solito è semplicemente un typedef a unsigned int. Il punto, però, è che non deve essere così. Tipi come size_t consentono al fornitore di librerie standard la libertà di modificare i propri tipi di dati sottostanti, se appropriato per la piattaforma. Se presumi che size_t sia sempre unsigned int (tramite casting, ecc.), Potresti incorrere in problemi in futuro se il tuo fornitore cambia size_t per essere, ad esempio, un tipo a 64 bit. È pericoloso presumere qualcosa su questo o qualsiasi altro tipo di libreria per questo motivo.
Non ho familiarità con void_tse non come risultato di una ricerca su Google (è utilizzato in una vmalloclibreria da Kiem-Phong Vo presso AT&T Research - sono sicuro che sia usato anche in altre biblioteche).
I vari typedef xxx_t sono usati per astrarre un tipo da una particolare implementazione definita, poiché i tipi concreti usati per certe cose potrebbero differire da una piattaforma all'altra. Per esempio:
Void_tastrae il tipo di puntatore restituito dalle vmallocroutine della libreria perché è stato scritto per funzionare su sistemi che precedono ANSI / ISO C dove ilvoid parola chiave potrebbe non esistere. Almeno questo è quello che immagino.wchar_t astrae il tipo usato per i caratteri larghi poiché su alcuni sistemi sarà un tipo a 16 bit, su altri sarà un tipo a 32 bit.Quindi, se scrivi il tuo codice per la gestione dei caratteri per usare il wchar_ttipo invece di, diciamo unsigned short, quel codice sarà presumibilmente più portabile su varie piattaforme.
Nei programmi minimalisti in cui una size_tdefinizione non è stata caricata "per caso" in alcuni include ma ne ho ancora bisogno in qualche contesto (ad esempio per accedere std::vector<double>), quindi utilizzo quel contesto per estrarre il tipo corretto. Per esempiotypedef std::vector<double>::size_type size_t .
(Circondare con namespace {...}se necessario per limitare l'ambito.)
Quanto a "Perché non utilizzare int o unsigned int?", Semplicemente perché semanticamente è più significativo non farlo. C'è la ragione pratica per cui può essere, diciamo, typedefd come un inte poi aggiornato a un longsecondo, senza che nessuno debba cambiare il proprio codice, ovviamente, ma più fondamentalmente di che un tipo dovrebbe essere significativo. Per semplificare enormemente, una variabile di tipo size_tè adatta e utilizzata per contenere le dimensioni delle cose, proprio come time_tè adatta per contenere valori temporali. Il modo in cui questi vengono effettivamente implementati dovrebbe essere abbastanza correttamente compito dell'implementazione. Rispetto alla semplice chiamata di tutto int, l'uso di nomi di tipo significativi come questo aiuta a chiarire il significato e l'intento del tuo programma, proprio come fa qualsiasi ricco insieme di tipi.